{"version":3,"file":"hls.worker.js.map","sources":["src/events.ts","src/errors.ts","src/crypt/aes-crypto.ts","src/crypt/fast-aes-key.ts","src/utils/typed-array.ts","src/crypt/aes-decryptor.ts","src/utils/logger.ts","src/polyfills/number.ts","node_modules/url-toolkit/src/url-toolkit.js","src/loader/fragment.ts","src/demux/id3.ts","src/utils/hex.ts","src/utils/mp4-tools.ts","src/crypt/decrypter.ts","src/types/demuxer.ts","src/demux/dummy-demuxed-track.ts","src/demux/audio/base-audio-demuxer.ts","src/demux/audio/adts.ts","src/demux/audio/mpegaudio.ts","src/demux/audio/aacdemuxer.ts","src/demux/mp4demuxer.ts","src/demux/audio/dolby.ts","src/demux/audio/ac3-demuxer.ts","src/demux/video/base-video-parser.ts","src/demux/video/exp-golomb.ts","src/demux/video/avc-video-parser.ts","src/demux/sample-aes.ts","src/demux/tsdemuxer.ts","src/demux/audio/mp3demuxer.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/codecs.ts","src/utils/mediasource-helper.ts","src/remux/passthrough-remuxer.ts","src/utils/global.ts","src/demux/transmuxer.ts","node_modules/eventemitter3/index.js","src/demux/transmuxer-worker.ts"],"sourcesContent":["import {\n  ManifestLoadedData,\n  ManifestLoadingData,\n  MediaAttachedData,\n  MediaAttachingData,\n  LevelLoadingData,\n  LevelLoadedData,\n  ManifestParsedData,\n  LevelUpdatedData,\n  LevelsUpdatedData,\n  FragParsingUserdataData,\n  FragDecryptedData,\n  FragLoadedData,\n  InitPTSFoundData,\n  CuesParsedData,\n  SubtitleFragProcessedData,\n  NonNativeTextTracksData,\n  FragLoadingData,\n  AudioTrackLoadedData,\n  SubtitleTrackLoadedData,\n  ErrorData,\n  AudioTrackSwitchingData,\n  AudioTrackSwitchedData,\n  KeyLoadedData,\n  KeyLoadingData,\n  SubtitleTrackSwitchData,\n  SubtitleTracksUpdatedData,\n  LevelSwitchedData,\n  FragChangedData,\n  BufferAppendingData,\n  BufferCodecsData,\n  FragParsingMetadataData,\n  FragParsingInitSegmentData,\n  FragBufferedData,\n  BufferFlushingData,\n  BufferEOSData,\n  LevelSwitchingData,\n  MaxAutoLevelUpdatedData,\n  FPSDropLevelCappingData,\n  FPSDropData,\n  BufferCreatedData,\n  BufferAppendedData,\n  LevelPTSUpdatedData,\n  FragParsedData,\n  AudioTracksUpdatedData,\n  FragLoadEmergencyAbortedData,\n  BackBufferData,\n  LiveBackBufferData,\n  TrackLoadingData,\n  BufferFlushedData,\n  SteeringManifestLoadedData,\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 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 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 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 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}\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]: (event: Events.MEDIA_DETACHING) => void;\n  [Events.MEDIA_DETACHED]: (event: Events.MEDIA_DETACHED) => 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.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.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_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}\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 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  // 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 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  // Uncategorized error\n  UNKNOWN = 'unknown',\n}\n","export default class AESCrypto {\n  private subtle: SubtleCrypto;\n  private aesIV: Uint8Array;\n\n  constructor(subtle: SubtleCrypto, iv: Uint8Array) {\n    this.subtle = subtle;\n    this.aesIV = iv;\n  }\n\n  decrypt(data: ArrayBuffer, key: CryptoKey) {\n    return this.subtle.decrypt({ name: 'AES-CBC', iv: this.aesIV }, key, data);\n  }\n}\n","export default class FastAESKey {\n  private subtle: SubtleCrypto;\n  private key: ArrayBuffer;\n\n  constructor(subtle: SubtleCrypto, key: ArrayBuffer) {\n    this.subtle = subtle;\n    this.key = key;\n  }\n\n  expandKey() {\n    return this.subtle.importKey('raw', this.key, { name: 'AES-CBC' }, false, [\n      'encrypt',\n      'decrypt',\n    ]);\n  }\n}\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","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","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\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\nlet exportedLogger: ILogger = fakeLogger;\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): ILogFunction {\n  const func: ILogFunction = self.console[type];\n  if (func) {\n    return func.bind(self.console, `[${type}] >`);\n  }\n  return noop;\n}\n\nfunction exportLoggerFunctions(\n  debugConfig: boolean | ILogger,\n  ...functions: string[]\n): void {\n  functions.forEach(function (type) {\n    exportedLogger[type] = debugConfig[type]\n      ? debugConfig[type].bind(debugConfig)\n      : consolePrintFn(type);\n  });\n}\n\nexport function enableLogs(debugConfig: boolean | ILogger, id: string): void {\n  // check that console is available\n  if (\n    (typeof console === 'object' && debugConfig === true) ||\n    typeof debugConfig === 'object'\n  ) {\n    exportLoggerFunctions(\n      debugConfig,\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    // Some browsers don't allow to use bind on console object anyway\n    // fallback to default if needed\n    try {\n      exportedLogger.log(\n        `Debug logs enabled for \"${id}\" in hls.js version ${__VERSION__}`,\n      );\n    } catch (e) {\n      exportedLogger = fakeLogger;\n    }\n  } else {\n    exportedLogger = fakeLogger;\n  }\n}\n\nexport const logger: ILogger = exportedLogger;\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","// 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 { LevelKey } from './level-key';\nimport { LoadStats } from './load-stats';\nimport { AttrList } from '../utils/attr-list';\nimport type {\n  FragmentLoaderContext,\n  KeyLoaderContext,\n  Loader,\n  PlaylistLevelType,\n} from '../types/loader';\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 class BaseSegment {\n  private _byteRange: [number, number] | null = null;\n  private _url: string | null = null;\n\n  // baseurl is the URL to the playlist\n  public readonly baseurl: string;\n  // relurl is the portion of the URL that comes from inside the playlist.\n  public relurl?: string;\n  // Holds the types of data this fragment supports\n  public elementaryStreams: ElementaryStreams = {\n    [ElementaryStreamTypes.AUDIO]: null,\n    [ElementaryStreamTypes.VIDEO]: null,\n    [ElementaryStreamTypes.AUDIOVIDEO]: null,\n  };\n\n  constructor(baseurl: string) {\n    this.baseurl = baseurl;\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 byteRange(): [number, number] | [] {\n    if (!this._byteRange) {\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 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\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\n  public rawProgramDateTime: string | null = null;\n  public programDateTime: number | 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  // 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  // Load/parse timing information\n  public stats: LoadStats = new LoadStats();\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, baseurl: string) {\n    super(baseurl);\n    this.type = type;\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    if (!Number.isFinite(this.programDateTime)) {\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\n    return false;\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  clearElementaryStreamInfo() {\n    const { elementaryStreams } = this;\n    elementaryStreams[ElementaryStreamTypes.AUDIO] = null;\n    elementaryStreams[ElementaryStreamTypes.VIDEO] = null;\n    elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null;\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: Fragment;\n  public readonly index: number;\n  public stats: LoadStats = new LoadStats();\n\n  constructor(\n    partAttrs: AttrList,\n    frag: Fragment,\n    baseurl: string,\n    index: number,\n    previous?: Part,\n  ) {\n    super(baseurl);\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","type RawFrame = { type: string; size: number; data: Uint8Array };\n\n// breaking up those two types in order to clarify what is happening in the decoding path.\ntype DecodedFrame<T> = { key: string; data: T; info?: any };\nexport type Frame = DecodedFrame<ArrayBuffer | string>;\n\n/**\n * Returns true if an ID3 header can be found at offset in data\n * @param data - The data to search\n * @param offset - The offset at which to start searching\n */\nexport const isHeader = (data: Uint8Array, offset: number): boolean => {\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 (\n      data[offset] === 0x49 &&\n      data[offset + 1] === 0x44 &&\n      data[offset + 2] === 0x33\n    ) {\n      // check version is within range\n      if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {\n        // check size is within range\n        if (\n          data[offset + 6] < 0x80 &&\n          data[offset + 7] < 0x80 &&\n          data[offset + 8] < 0x80 &&\n          data[offset + 9] < 0x80\n        ) {\n          return true;\n        }\n      }\n    }\n  }\n\n  return false;\n};\n\n/**\n * Returns true if an ID3 footer can be found at offset in data\n * @param data - The data to search\n * @param offset - The offset at which to start searching\n */\nexport const isFooter = (data: Uint8Array, offset: number): boolean => {\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 (\n      data[offset] === 0x33 &&\n      data[offset + 1] === 0x44 &&\n      data[offset + 2] === 0x49\n    ) {\n      // check version is within range\n      if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {\n        // check size is within range\n        if (\n          data[offset + 6] < 0x80 &&\n          data[offset + 7] < 0x80 &&\n          data[offset + 8] < 0x80 &&\n          data[offset + 9] < 0x80\n        ) {\n          return true;\n        }\n      }\n    }\n  }\n\n  return false;\n};\n\n/**\n * Returns any adjacent ID3 tags found in data starting at offset, as one block of data\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n * @returns the block of data containing any ID3 tags found\n * or *undefined* if no header is found at the starting offset\n */\nexport const getID3Data = (\n  data: Uint8Array,\n  offset: number,\n): Uint8Array | undefined => {\n  const front = offset;\n  let length = 0;\n\n  while (isHeader(data, offset)) {\n    // ID3 header is 10 bytes\n    length += 10;\n\n    const size = readSize(data, offset + 6);\n    length += size;\n\n    if (isFooter(data, offset + 10)) {\n      // ID3 footer is 10 bytes\n      length += 10;\n    }\n\n    offset += length;\n  }\n\n  if (length > 0) {\n    return data.subarray(front, front + length);\n  }\n\n  return undefined;\n};\n\nconst readSize = (data: Uint8Array, offset: number): number => {\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\nexport const canParse = (data: Uint8Array, offset: number): boolean => {\n  return (\n    isHeader(data, offset) &&\n    readSize(data, offset + 6) + 10 <= data.length - offset\n  );\n};\n\n/**\n * Searches for the Elementary Stream timestamp found in the ID3 data chunk\n * @param data - Block of data containing one or more ID3 tags\n */\nexport const getTimeStamp = (data: Uint8Array): number | undefined => {\n  const frames: Frame[] = getID3Frames(data);\n\n  for (let i = 0; i < frames.length; i++) {\n    const frame = frames[i];\n\n    if (isTimeStampFrame(frame)) {\n      return readTimeStamp(frame as DecodedFrame<ArrayBuffer>);\n    }\n  }\n\n  return undefined;\n};\n\n/**\n * Returns true if the ID3 frame is an Elementary Stream timestamp frame\n */\nexport const isTimeStampFrame = (frame: Frame): boolean => {\n  return (\n    frame &&\n    frame.key === 'PRIV' &&\n    frame.info === 'com.apple.streaming.transportStreamTimestamp'\n  );\n};\n\nconst getFrameData = (data: Uint8Array): RawFrame => {\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 = String.fromCharCode(data[0], data[1], data[2], data[3]);\n  const size: number = readSize(data, 4);\n\n  // skip frame id, size, and flags\n  const offset = 10;\n\n  return { type, size, data: data.subarray(offset, offset + size) };\n};\n\n/**\n * Returns an array of ID3 frames found in all the ID3 tags in the id3Data\n * @param id3Data - The ID3 data containing one or more ID3 tags\n */\nexport const getID3Frames = (id3Data: Uint8Array): Frame[] => {\n  let offset = 0;\n  const frames: Frame[] = [];\n\n  while (isHeader(id3Data, offset)) {\n    const size = readSize(id3Data, offset + 6);\n    // skip past ID3 header\n    offset += 10;\n    const end = offset + size;\n    // loop through frames in the ID3 tag\n    while (offset + 8 < end) {\n      const frameData: RawFrame = getFrameData(id3Data.subarray(offset));\n      const frame: Frame | undefined = decodeFrame(frameData);\n      if (frame) {\n        frames.push(frame);\n      }\n\n      // skip frame header and frame data\n      offset += frameData.size + 10;\n    }\n\n    if (isFooter(id3Data, offset)) {\n      offset += 10;\n    }\n  }\n\n  return frames;\n};\n\nexport const decodeFrame = (frame: RawFrame): Frame | undefined => {\n  if (frame.type === 'PRIV') {\n    return decodePrivFrame(frame);\n  } else if (frame.type[0] === 'W') {\n    return decodeURLFrame(frame);\n  }\n\n  return decodeTextFrame(frame);\n};\n\nconst decodePrivFrame = (\n  frame: RawFrame,\n): DecodedFrame<ArrayBuffer> | undefined => {\n  /*\n  Format: <text string>\\0<binary data>\n  */\n  if (frame.size < 2) {\n    return undefined;\n  }\n\n  const owner = utf8ArrayToStr(frame.data, true);\n  const privateData = new Uint8Array(frame.data.subarray(owner.length + 1));\n\n  return { key: frame.type, info: owner, data: privateData.buffer };\n};\n\nconst decodeTextFrame = (frame: RawFrame): DecodedFrame<string> | undefined => {\n  if (frame.size < 2) {\n    return undefined;\n  }\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\n    index += description.length + 1;\n    const value = utf8ArrayToStr(frame.data.subarray(index));\n\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, data: text };\n};\n\nconst decodeURLFrame = (frame: RawFrame): DecodedFrame<string> | undefined => {\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\n    let index = 1;\n    const description: string = utf8ArrayToStr(\n      frame.data.subarray(index),\n      true,\n    );\n\n    index += description.length + 1;\n    const value: string = utf8ArrayToStr(frame.data.subarray(index));\n\n    return { key: frame.type, info: description, data: value };\n  }\n  /*\n  Format:\n  [0-?] = {URL}\n  */\n  const url: string = utf8ArrayToStr(frame.data);\n  return { key: frame.type, data: url };\n};\n\nconst readTimeStamp = (\n  timeStampFrame: DecodedFrame<ArrayBuffer>,\n): number | undefined => {\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 =\n      (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7];\n    timestamp /= 45;\n\n    if (pts33Bit) {\n      timestamp += 47721858.84;\n    } // 2^32 / 90\n\n    return Math.round(timestamp);\n  }\n\n  return undefined;\n};\n\n// 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 */\nexport const utf8ArrayToStr = (\n  array: Uint8Array,\n  exitOnNull: boolean = false,\n): string => {\n  const decoder = getTextDecoder();\n  if (decoder) {\n    const decoded = decoder.decode(array);\n\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\n    // remove any null characters\n    return decoded.replace(/\\0/g, '');\n  }\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    } 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(\n          ((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0),\n        );\n        break;\n      default:\n    }\n  }\n  return out;\n};\n\nexport const testables = {\n  decodeTextFrame: decodeTextFrame,\n};\n\nlet decoder: TextDecoder;\n\nfunction getTextDecoder() {\n  // On Play Station 4, TextDecoder is defined but partially implemented.\n  // Manual decoding option is preferable\n  if (navigator.userAgent.includes('PlayStation 4')) {\n    return;\n  }\n\n  if (!decoder && typeof self.TextDecoder !== 'undefined') {\n    decoder = new self.TextDecoder('utf-8');\n  }\n\n  return decoder;\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","import { ElementaryStreamTypes } from '../loader/fragment';\nimport { sliceUint8 } from './typed-array';\nimport { utf8ArrayToStr } from '../demux/id3';\nimport { logger } from '../utils/logger';\nimport Hex from './hex';\nimport type { KeySystemIds } from './mediakeys-helper';\nimport type { PassthroughTrack, UserdataSample } from '../types/demuxer';\nimport type { DecryptData } from '../loader/level-key';\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 > 12) {\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  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 AESCrypto from './aes-crypto';\nimport FastAESKey from './fast-aes-key';\nimport AESDecryptor, { removePadding } from './aes-decryptor';\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\n  constructor(config: HlsConfig, { removePKCS7Padding = true } = {}) {\n    this.useSoftware = 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\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  ): Promise<ArrayBuffer> {\n    if (this.useSoftware) {\n      return new Promise((resolve, reject) => {\n        this.softwareDecrypt(new Uint8Array(data), key, iv);\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);\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  ): ArrayBuffer | null {\n    const { currentIV, currentResult, remainderData } = this;\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  ): Promise<ArrayBuffer> {\n    if (this.key !== key || !this.fastAesKey) {\n      if (!this.subtle) {\n        return Promise.resolve(this.onWebCryptoError(data, key, iv));\n      }\n      this.key = key;\n      this.fastAesKey = new FastAESKey(this.subtle, key);\n    }\n    return this.fastAesKey\n      .expandKey()\n      .then((aesKey) => {\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));\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);\n      });\n  }\n\n  private onWebCryptoError(\n    data: Uint8Array,\n    key: ArrayBuffer,\n    iv: ArrayBuffer,\n  ): ArrayBuffer | never {\n    this.useSoftware = true;\n    this.logEnabled = true;\n    this.softwareDecrypt(data, key, iv);\n    const decryptResult = this.flush();\n    if (decryptResult) {\n      return decryptResult.buffer;\n    }\n    throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');\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","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  config?: number[] | Uint8Array;\n  samplerate?: number;\n  segmentCodec?: string;\n  channelCount?: number;\n  manifestCodec?: string;\n  samples: AudioSample[];\n}\n\nexport interface DemuxedVideoTrackBase extends DemuxedTrack {\n  width?: number;\n  height?: number;\n  pixelRatio?: [number, number];\n  audFound?: boolean;\n  pps?: Uint8Array[];\n  sps?: Uint8Array[];\n  naluState?: number;\n  segmentCodec?: string;\n  manifestCodec?: string;\n  samples: VideoSample[] | Uint8Array;\n}\n\nexport interface DemuxedVideoTrack extends DemuxedVideoTrackBase {\n  samples: VideoSample[];\n}\n\nexport interface DemuxedMetadataTrack extends DemuxedTrack {\n  samples: MetadataSample[];\n}\n\nexport interface DemuxedUserdataTrack extends DemuxedTrack {\n  samples: UserdataSample[];\n}\n\nexport const enum MetadataSchema {\n  audioId3 = 'org.id3',\n  dateRange = 'com.apple.quicktime.HLS',\n  emsg = 'https://aomedia.org/emsg/ID3',\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  debug: string;\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","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 * as ID3 from '../id3';\nimport {\n  DemuxerResult,\n  Demuxer,\n  DemuxedAudioTrack,\n  AudioFrame,\n  DemuxedMetadataTrack,\n  DemuxedVideoTrackBase,\n  DemuxedUserdataTrack,\n  KeyData,\n  MetadataSchema,\n} from '../../types/demuxer';\nimport { dummyTrack } from '../dummy-demuxed-track';\nimport { appendUint8Array } from '../../utils/mp4-tools';\nimport { sliceUint8 } from '../../utils/typed-array';\nimport { 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 = ID3.getID3Data(data, 0);\n    let offset = id3Data ? id3Data.length : 0;\n    let lastDataIndex;\n    const track = this._audioTrack;\n    const id3Track = this._id3Track;\n    const timestamp = id3Data ? ID3.getTimeStamp(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 (ID3.canParse(data, offset)) {\n        // after a ID3.canParse, a call to ID3.getID3Data *should* always returns some data\n        id3Data = ID3.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,\n      videoTrack: dummyTrack() as DemuxedVideoTrackBase,\n      id3Track: this._id3Track,\n      textTrack: dummyTrack() as DemuxedUserdataTrack,\n    };\n  }\n\n  destroy() {}\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 * ADTS parser helper\n * @link https://wiki.multimedia.cx/index.php?title=ADTS\n */\nimport { logger } from '../../utils/logger';\nimport { ErrorTypes, ErrorDetails } from '../../errors';\nimport type { HlsEventEmitter } from '../../events';\nimport { Events } from '../../events';\nimport type {\n  DemuxedAudioTrack,\n  AudioFrame,\n  AudioSample,\n} from '../../types/demuxer';\n\ntype AudioConfig = {\n  config: number[];\n  samplerate: number;\n  channelCount: number;\n  codec: string;\n  manifestCodec: string;\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  audioCodec: string,\n): AudioConfig | void {\n  let adtsObjectType: number;\n  let adtsExtensionSamplingIndex: number;\n  let adtsChannelConfig: number;\n  let config: number[];\n  const userAgent = navigator.userAgent.toLowerCase();\n  const manifestCodec = audioCodec;\n  const adtsSamplingRates = [\n    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025,\n    8000, 7350,\n  ];\n  // byte 2\n  adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;\n  const adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;\n  if (adtsSamplingIndex > adtsSamplingRates.length - 1) {\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  adtsChannelConfig = (data[offset + 2] & 0x01) << 2;\n  // byte 3\n  adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;\n  logger.log(\n    `manifest codec:${audioCodec}, ADTS type:${adtsObjectType}, samplingIndex:${adtsSamplingIndex}`,\n  );\n  // firefox: freq less than 24kHz = AAC SBR (HE-AAC)\n  if (/firefox/i.test(userAgent)) {\n    if (adtsSamplingIndex >= 6) {\n      adtsObjectType = 5;\n      config = new Array(4);\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 below, equivalent to substract 3)\n      adtsExtensionSamplingIndex = adtsSamplingIndex - 3;\n    } else {\n      adtsObjectType = 2;\n      config = new Array(2);\n      adtsExtensionSamplingIndex = adtsSamplingIndex;\n    }\n    // Android : always use AAC\n  } else if (userAgent.indexOf('android') !== -1) {\n    adtsObjectType = 2;\n    config = new Array(2);\n    adtsExtensionSamplingIndex = adtsSamplingIndex;\n  } else {\n    /*  for other browsers (Chrome/Vivaldi/Opera ...)\n        always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)\n    */\n    adtsObjectType = 5;\n    config = new Array(4);\n    // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)\n    if (\n      (audioCodec &&\n        (audioCodec.indexOf('mp4a.40.29') !== -1 ||\n          audioCodec.indexOf('mp4a.40.5') !== -1)) ||\n      (!audioCodec && adtsSamplingIndex >= 6)\n    ) {\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 below, equivalent to substract 3)\n      adtsExtensionSamplingIndex = adtsSamplingIndex - 3;\n    } else {\n      // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)\n      // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC.  This is not a problem with stereo.\n      if (\n        (audioCodec &&\n          audioCodec.indexOf('mp4a.40.2') !== -1 &&\n          ((adtsSamplingIndex >= 6 && adtsChannelConfig === 1) ||\n            /vivaldi/i.test(userAgent))) ||\n        (!audioCodec && adtsChannelConfig === 1)\n      ) {\n        adtsObjectType = 2;\n        config = new Array(2);\n      }\n      adtsExtensionSamplingIndex = adtsSamplingIndex;\n    }\n  }\n  /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config\n      ISO 14496-3 (AAC).pdf - 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  config[0] = adtsObjectType << 3;\n  // samplingFrequencyIndex\n  config[0] |= (adtsSamplingIndex & 0x0e) >> 1;\n  config[1] |= (adtsSamplingIndex & 0x01) << 7;\n  // channelConfiguration\n  config[1] |= adtsChannelConfig << 3;\n  if (adtsObjectType === 5) {\n    // adtsExtensionSamplingIndex\n    config[1] |= (adtsExtensionSamplingIndex & 0x0e) >> 1;\n    config[2] = (adtsExtensionSamplingIndex & 0x01) << 7;\n    // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ???\n    //    https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc\n    config[2] |= 2 << 2;\n    config[3] = 0;\n  }\n  return {\n    config,\n    samplerate: adtsSamplingRates[adtsSamplingIndex],\n    channelCount: adtsChannelConfig,\n    codec: 'mp4a.40.' + adtsObjectType,\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,\n) {\n  if (!track.samplerate) {\n    const config = getAudioConfig(observer, data, offset, audioCodec);\n    if (!config) {\n      return;\n    }\n    track.config = config.config;\n    track.samplerate = config.samplerate;\n    track.channelCount = config.channelCount;\n    track.codec = config.codec;\n    track.manifestCodec = config.manifestCodec;\n    logger.log(\n      `parsed codec:${track.codec}, rate:${config.samplerate}, channels:${config.channelCount}`,\n    );\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","/**\n *  MPEG parser helper\n */\nimport { 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 BaseAudioDemuxer from './base-audio-demuxer';\nimport * as ADTS from './adts';\nimport * as MpegAudio from './mpegaudio';\nimport { logger } from '../../utils/logger';\nimport * as ID3 from '../id3';\nimport type { HlsEventEmitter } from '../../events';\nimport type { HlsConfig } from '../../config';\n\nclass AACDemuxer extends BaseAudioDemuxer {\n  private readonly observer: HlsEventEmitter;\n  private readonly config: HlsConfig;\n\n  constructor(observer, 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): 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 = ID3.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, data, offset) {\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","/**\n * MP4 demuxer\n */\nimport {\n  Demuxer,\n  DemuxerResult,\n  PassthroughTrack,\n  DemuxedAudioTrack,\n  DemuxedUserdataTrack,\n  DemuxedMetadataTrack,\n  KeyData,\n  MetadataSchema,\n} from '../types/demuxer';\nimport {\n  findBox,\n  segmentValidRange,\n  appendUint8Array,\n  parseEmsg,\n  parseSamples,\n  parseInitSegment,\n  RemuxerTrackIdConfig,\n  hasMoofData,\n} from '../utils/mp4-tools';\nimport { dummyTrack } from './dummy-demuxed-track';\nimport type { HlsEventEmitter } from '../events';\nimport type { HlsConfig } from '../config';\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\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 = Number.isFinite(emsgInfo.presentationTime)\n              ? emsgInfo.presentationTime! / emsgInfo.timeScale\n              : timeOffset +\n                emsgInfo.presentationTimeDelta! / emsgInfo.timeScale;\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          }\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}\n\nexport default MP4Demuxer;\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 BaseAudioDemuxer from './base-audio-demuxer';\nimport { getID3Data, getTimeStamp } from '../id3';\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) {\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      getTimeStamp(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","import type { ParsedVideoSample } from '../tsdemuxer';\nimport {\n  DemuxedVideoTrack,\n  VideoSample,\n  VideoSampleUnit,\n} from '../../types/demuxer';\nimport { logger } from '../../utils/logger';\n\nclass BaseVideoParser {\n  protected VideoSample: ParsedVideoSample | null = null;\n\n  protected createVideoSample(\n    key: boolean,\n    pts: number | undefined,\n    dts: number | undefined,\n    debug: string,\n  ): ParsedVideoSample {\n    return {\n      key,\n      frame: false,\n      pts,\n      dts,\n      units: [],\n      debug,\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    if (VideoSample.debug.length) {\n      logger.log(\n        VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug,\n      );\n    }\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  /**\n   * Advance the ExpGolomb decoder past a scaling list. The scaling\n   * 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): 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 = this.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(): {\n    width: number;\n    height: number;\n    pixelRatio: [number, number];\n  } {\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 = this.readUByte.bind(this);\n    const readBits = this.readBits.bind(this);\n    const readUEG = this.readUEG.bind(this);\n    const readBoolean = this.readBoolean.bind(this);\n    const skipBits = this.skipBits.bind(this);\n    const skipEG = this.skipEG.bind(this);\n    const skipUEG = this.skipUEG.bind(this);\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);\n            } else {\n              skipScalingList(64);\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  readSliceType() {\n    // skip NALu type\n    this.readUByte();\n    // discard first_mb_in_slice\n    this.readUEG();\n    // return slice_type\n    return this.readUEG();\n  }\n}\n\nexport default ExpGolomb;\n","import BaseVideoParser from './base-video-parser';\nimport {\n  DemuxedVideoTrack,\n  DemuxedUserdataTrack,\n  VideoSampleUnit,\n} from '../../types/demuxer';\nimport {\n  appendUint8Array,\n  parseSEIMessageFromNALu,\n} from '../../utils/mp4-tools';\nimport ExpGolomb from './exp-golomb';\nimport type { PES } from '../tsdemuxer';\n\nclass AvcVideoParser extends BaseVideoParser {\n  public parseAVCPES(\n    track: DemuxedVideoTrack,\n    textTrack: DemuxedUserdataTrack,\n    pes: PES,\n    last: boolean,\n    duration: number,\n  ) {\n    const units = this.parseAVCNALu(track, pes.data);\n    const debug = false;\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\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 = new ExpGolomb(data).readSliceType();\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          }\n\n          if (debug) {\n            VideoSample.debug += 'NDR ';\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\n          if (debug) {\n            VideoSample.debug += 'IDR ';\n          }\n\n          VideoSample.key = true;\n          VideoSample.frame = true;\n          break;\n        // SEI\n        case 6: {\n          push = true;\n          if (debug && VideoSample) {\n            VideoSample.debug += 'SEI ';\n          }\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          if (debug && VideoSample) {\n            VideoSample.debug += 'SPS ';\n          }\n          const sps = unit.data;\n          const expGolombDecoder = new ExpGolomb(sps);\n          const config = expGolombDecoder.readSPS();\n\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            track.duration = duration;\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\n          break;\n        }\n        // PPS\n        case 8:\n          push = true;\n          if (debug && VideoSample) {\n            VideoSample.debug += 'PPS ';\n          }\n\n          track.pps = [unit.data];\n\n          break;\n        // AUD\n        case 9:\n          push = true;\n          track.audFound = true;\n          if (VideoSample) {\n            this.pushAccessUnit(VideoSample, track);\n          }\n\n          VideoSample = this.VideoSample = this.createVideoSample(\n            false,\n            pes.pts,\n            pes.dts,\n            debug ? 'AUD ' : '',\n          );\n          break;\n        // Filler Data\n        case 12:\n          push = true;\n          break;\n        default:\n          push = false;\n          if (VideoSample) {\n            VideoSample.debug += 'unknown NAL ' + unit.type + ' ';\n          }\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 (last && VideoSample) {\n      this.pushAccessUnit(VideoSample, track);\n      this.VideoSample = null;\n    }\n  }\n\n  private parseAVCNALu(\n    track: DemuxedVideoTrack,\n    array: Uint8Array,\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 = array[0] & 0x1f;\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 = array[i] & 0x1f;\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 AvcVideoParser;\n","/**\n * SAMPLE-AES decrypter\n */\n\nimport { HlsConfig } from '../config';\nimport Decrypter from '../crypt/decrypter';\nimport { HlsEventEmitter } from '../events';\nimport type {\n  AudioSample,\n  VideoSample,\n  VideoSampleUnit,\n  DemuxedVideoTrackBase,\n  KeyData,\n} from '../types/demuxer';\nimport { discardEPB } from '../utils/mp4-tools';\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    );\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","/**\n * highly optimized TS demuxer:\n * parse PAT, PMT\n * extract PES packet from audio and video PIDs\n * extract AVC/H264 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 ADTS from './audio/adts';\nimport * as MpegAudio from './audio/mpegaudio';\nimport * as AC3 from './audio/ac3-demuxer';\nimport AvcVideoParser from './video/avc-video-parser';\nimport SampleAesDecrypter from './sample-aes';\nimport { Events } from '../events';\nimport { appendUint8Array, RemuxerTrackIdConfig } from '../utils/mp4-tools';\nimport { logger } from '../utils/logger';\nimport { ErrorTypes, ErrorDetails } from '../errors';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport {\n  DemuxedVideoTrack,\n  DemuxedAudioTrack,\n  DemuxedTrack,\n  Demuxer,\n  DemuxerResult,\n  VideoSample,\n  DemuxedMetadataTrack,\n  DemuxedUserdataTrack,\n  ElementaryStreamData,\n  KeyData,\n  MetadataSchema,\n} from '../types/demuxer';\nimport { AudioFrame } from '../types/demuxer';\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\nexport interface TypeSupported {\n  mpeg: boolean;\n  mp3: boolean;\n  ac3: boolean;\n}\n\nconst PACKET_LENGTH = 188;\n\nclass TSDemuxer implements Demuxer {\n  private readonly observer: HlsEventEmitter;\n  private readonly config: HlsConfig;\n  private typeSupported: TypeSupported;\n\n  private sampleAes: SampleAesDecrypter | null = null;\n  private pmtParsed: boolean = false;\n  private audioCodec?: string;\n  private videoCodec?: string;\n  private _duration: number = 0;\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: AvcVideoParser;\n\n  constructor(\n    observer: HlsEventEmitter,\n    config: HlsConfig,\n    typeSupported: TypeSupported,\n  ) {\n    this.observer = observer;\n    this.config = config;\n    this.typeSupported = typeSupported;\n    this.videoParser = new AvcVideoParser();\n  }\n\n  static probe(data: Uint8Array) {\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._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    this._duration = trackDuration;\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))) {\n                this.videoParser.parseAVCPES(\n                  videoTrack,\n                  textTrack,\n                  pes,\n                  false,\n                  this._duration,\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))) {\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))) {\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            // 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            );\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              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      );\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))) {\n      this.videoParser.parseAVCPES(\n        videoTrack as DemuxedVideoTrack,\n        textTrack as DemuxedUserdataTrack,\n        pes,\n        true,\n        this._duration,\n      );\n      videoTrack.pesData = null;\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))) {\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        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))) {\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    this._duration = 0;\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(this.observer, new Error(reason), recoverable);\n      if (!recoverable) {\n        return;\n      }\n    }\n\n    ADTS.initTrackConfig(\n      track,\n      this.observer,\n      data,\n      offset,\n      this.audioCodec as string,\n    );\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      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      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        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      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) {\n  const result = {\n    audioPid: -1,\n    videoPid: -1,\n    id3Pid: -1,\n    segmentVideoCodec: 'avc',\n    segmentAudioCodec: 'aac',\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');\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');\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          result.segmentVideoCodec = 'avc';\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');\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(observer, new Error('Unsupported EC-3 in M2TS found'));\n        return result;\n\n      case 0x24:\n        emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'));\n        return result;\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,\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(type: string) {\n  logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);\n}\n\nfunction parsePES(stream: ElementaryStreamData): 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 * MP3 demuxer\n */\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport { getID3Data, getTimeStamp } from '../id3';\nimport { getAudioBSID } from './dolby';\nimport { logger } from '../../utils/logger';\nimport * as MpegAudio from './mpegaudio';\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      getTimeStamp(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","/**\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';\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      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, ...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) {\n    return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);\n  }\n\n  static mdat(data) {\n    return MP4.box(MP4.types.mdat, data);\n  }\n\n  static mdhd(timescale, duration) {\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) {\n    return MP4.box(\n      MP4.types.mdia,\n      MP4.mdhd(track.timescale, track.duration),\n      MP4.hdlr(track.type),\n      MP4.minf(track),\n    );\n  }\n\n  static mfhd(sequenceNumber) {\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) {\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(sn, baseMediaDecodeTime, track) {\n    return MP4.box(\n      MP4.types.moof,\n      MP4.mfhd(sn),\n      MP4.traf(track, baseMediaDecodeTime),\n    );\n  }\n\n  static moov(tracks) {\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      [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)]\n        .concat(boxes)\n        .concat(MP4.mvex(tracks)),\n    );\n  }\n\n  static mvex(tracks) {\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, duration) {\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) {\n    const samples = track.samples || [];\n    const bytes = new Uint8Array(4 + samples.length);\n    let i;\n    let flags;\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) {\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) {\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) {\n    const configlen = track.config.length;\n    return new Uint8Array(\n      [\n        0x00, // version 0\n        0x00,\n        0x00,\n        0x00, // flags\n\n        0x03, // descriptor_type\n        0x17 + configlen, // length\n        0x00,\n        0x01, // es_id\n        0x00, // stream_priority\n\n        0x04, // descriptor_type\n        0x0f + configlen, // 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      ]\n        .concat([configlen])\n        .concat(track.config)\n        .concat([0x06, 0x01, 0x02]),\n    ); // GASpecificConfig)); // length + audio config descriptor\n  }\n\n  static audioStsd(track) {\n    const samplerate = track.samplerate;\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, // 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) {\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) {\n    return MP4.box(MP4.types['.mp3'], MP4.audioStsd(track));\n  }\n\n  static ac3(track) {\n    return MP4.box(\n      MP4.types['ac-3'],\n      MP4.audioStsd(track),\n      MP4.box(MP4.types.dac3, track.config),\n    );\n  }\n\n  static stsd(track) {\n    if (track.type === 'audio') {\n      if (track.segmentCodec === 'mp3' && track.codec === 'mp3') {\n        return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track));\n      }\n      if (track.segmentCodec === 'ac3') {\n        return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));\n      }\n      return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));\n    } else {\n      return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));\n    }\n  }\n\n  static tkhd(track) {\n    const id = track.id;\n    const duration = track.duration * track.timescale;\n    const width = track.width;\n    const height = track.height;\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, baseMediaDecodeTime) {\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) {\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) {\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, offset) {\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) {\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\nexport default MP4;\n","import type { LoaderConfig } from '../config';\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';\nimport type { HlsUrlParameters } from './level';\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}\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 type { HlsEventEmitter } from '../events';\nimport { Events } from '../events';\nimport { ErrorTypes, ErrorDetails } from '../errors';\nimport { logger } from '../utils/logger';\nimport {\n  InitSegmentData,\n  Remuxer,\n  RemuxerResult,\n  RemuxedMetadata,\n  RemuxedTrack,\n  RemuxedUserdata,\n} from '../types/remuxer';\nimport { PlaylistLevelType } from '../types/loader';\nimport {\n  RationalTimestamp,\n  toMsFromMpegTsClock,\n} from '../utils/timescale-conversion';\nimport type {\n  AudioSample,\n  VideoSample,\n  DemuxedAudioTrack,\n  DemuxedVideoTrack,\n  DemuxedMetadataTrack,\n  DemuxedUserdataTrack,\n} from '../types/demuxer';\nimport type { TrackSet } from '../types/track';\nimport type { SourceBufferName } from '../types/buffer';\nimport type { Fragment } from '../loader/fragment';\nimport type { HlsConfig } from '../config';\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\nexport default class MP4Remuxer implements Remuxer {\n  private observer: HlsEventEmitter;\n  private config: HlsConfig;\n  private typeSupported: any;\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,\n    vendor = '',\n  ) {\n    this.observer = observer;\n    this.config = config;\n    this.typeSupported = typeSupported;\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    logger.log('[mp4-remuxer]: initPTS & initDTS reset');\n    this._initPTS = this._initDTS = defaultTimeStamp;\n  }\n\n  resetNextTimestamp() {\n    logger.log('[mp4-remuxer]: reset next timestamp');\n    this.isVideoContiguous = false;\n    this.isAudioContiguous = false;\n  }\n\n  resetInitSegment() {\n    logger.log('[mp4-remuxer]: ISGenerated flag reset');\n    this.ISGenerated = false;\n    this.videoTrackConfig = undefined;\n  }\n\n  getVideoStartPts(videoSamples) {\n    let rolloverDetected = false;\n    const startPTS = videoSamples.reduce((minPTS, sample) => {\n      const delta = sample.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        return normalizePts(minPTS, sample.pts);\n      } else if (delta > 0) {\n        return minPTS;\n      } else {\n        return sample.pts;\n      }\n    }, videoSamples[0].pts);\n    if (rolloverDetected) {\n      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        ) {\n          this.resetInitSegment();\n        }\n      } else {\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            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            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            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              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          logger.warn(\n            `AVC: ${toMsFromMpegTsClock(\n              delta,\n              true,\n            )} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(\n              3,\n            )}`,\n          );\n        } else {\n          logger.warn(\n            `AVC: ${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            for (let i = 0; i < inputSamples.length; i++) {\n              if (inputSamples[i].dts > firstPTS) {\n                break;\n              }\n              inputSamples[i].dts -= delta;\n              inputSamples[i].pts -= delta;\n            }\n          }\n          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            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        new Mp4Sample(\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          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 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            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          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.manifestCodec || track.codec,\n              track.channelCount,\n            );\n            if (!fillFrame) {\n              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(new Mp4Sample(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  remuxEmptyAudio(\n    track: DemuxedAudioTrack,\n    timeOffset: number,\n    contiguous: boolean,\n    videoData: Fragment,\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 nextAudioPts: number | null = this.nextAudioPts;\n    // sync with video's timestamp\n    const initDTS = this._initDTS as RationalTimestamp;\n    const init90kHz = (initDTS.baseTime * 90000) / initDTS.timescale;\n    const startDTS: number =\n      (nextAudioPts !== null\n        ? nextAudioPts\n        : videoData.startDTS * inputTimeScale) + init90kHz;\n    const endDTS: number = videoData.endDTS * inputTimeScale + init90kHz;\n    // one sample's duration value\n    const frameDuration: number = scaleFactor * AAC_SAMPLES_PER_FRAME;\n    // samples count of this segment's duration\n    const nbSamples: number = Math.ceil((endDTS - startDTS) / frameDuration);\n    // silent frame\n    const silentFrame: Uint8Array | undefined = AAC.getSilentFrame(\n      track.manifestCodec || track.codec,\n      track.channelCount,\n    );\n\n    logger.warn('[mp4-remuxer]: remux empty Audio');\n    // Can't remux if we can't generate a silent frame...\n    if (!silentFrame) {\n      logger.trace(\n        '[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec',\n      );\n      return;\n    }\n\n    const samples: Array<any> = [];\n    for (let i = 0; i < nbSamples; i++) {\n      const stamp = startDTS + i * frameDuration;\n      samples.push({ unit: silentFrame, pts: stamp, dts: stamp });\n    }\n    track.samples = samples;\n\n    return this.remuxAudio(track, timeOffset, contiguous, false);\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\ntype Mp4SampleFlags = {\n  isLeading: 0;\n  isDependedOn: 0;\n  hasRedundancy: 0;\n  degradPrio: 0;\n  dependsOn: 1 | 2;\n  isNonSync: 0 | 1;\n};\n\nclass Mp4Sample {\n  public size: number;\n  public duration: number;\n  public cts: number;\n  public flags: Mp4SampleFlags;\n\n  constructor(\n    isKeyframe: boolean,\n    duration: number,\n    size: number,\n    cts: number,\n  ) {\n    this.duration = duration;\n    this.size = size;\n    this.cts = cts;\n    this.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}\n","import { getMediaSource } from './mediasource-helper';\n\n// from http://mp4ra.org/codecs.html\n// values indicate codec selection preference (lower is higher priority)\nconst 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  // 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  const codecsToCheck = {\n    flac: ['flac', 'fLaC', 'FLAC'],\n    opus: ['opus', 'Opus'],\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    }\n  }\n\n  return lowerCaseCodec;\n}\n\nconst AUDIO_CODEC_REGEXP = /flac|opus/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,\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 (parsedCodec && parsedCodec !== 'mp4a') {\n    return parsedCodec;\n  }\n  return levelCodec ? levelCodec.split(',')[0] : levelCodec;\n}\n\nexport function convertAVC1ToAVCOTI(codec: 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 = codec.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","/**\n * MediaSource helper\n */\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","import {\n  flushTextTrackMetadataCueSamples,\n  flushTextTrackUserdataCueSamples,\n} from './mp4-remuxer';\nimport {\n  InitData,\n  InitDataTrack,\n  patchEncyptionData,\n} from '../utils/mp4-tools';\nimport {\n  getDuration,\n  getStartDTS,\n  offsetStartDTS,\n  parseInitSegment,\n} from '../utils/mp4-tools';\nimport { ElementaryStreamTypes } from '../loader/fragment';\nimport { logger } from '../utils/logger';\nimport { getCodecCompatibleName } from '../utils/codecs';\nimport type { TrackSet } from '../types/track';\nimport type {\n  InitSegmentData,\n  RemuxedTrack,\n  Remuxer,\n  RemuxerResult,\n} from '../types/remuxer';\nimport type {\n  DemuxedAudioTrack,\n  DemuxedMetadataTrack,\n  DemuxedUserdataTrack,\n  PassthroughTrack,\n} from '../types/demuxer';\nimport type { DecryptData } from '../loader/level-key';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nclass PassThroughRemuxer implements Remuxer {\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  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 or fallback to default\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      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      logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');\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      isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) ||\n      (initSegment.timescale !== initPTS.timescale && accurateTimeOffset)\n    ) {\n      initSegment.initPTS = decodeTime - timeOffset;\n      if (initPTS && initPTS.timescale === 1) {\n        logger.warn(\n          `Adjusting initPTS by ${initSegment.initPTS - initPTS.baseTime}`,\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      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    const result = 'mp4a.40.5';\n    logger.info(\n      `Parsed audio codec \"${parsedCodec}\" or audio object type not handled. Using \"${result}\"`,\n    );\n    return result;\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}\"`);\n  if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {\n    return 'hvc1.1.6.L120.90';\n  }\n  if (parsedCodec === 'av01') {\n    return 'av01.0.04M.08';\n  }\n  return 'avc1.42e01e';\n}\nexport default PassThroughRemuxer;\n","/** returns `undefined` is `self` is missing, e.g. in node */\nexport const optionalSelf = typeof self !== 'undefined' ? self : undefined;\n","import type { HlsEventEmitter } from '../events';\nimport { Events } from '../events';\nimport { ErrorTypes, ErrorDetails } from '../errors';\nimport Decrypter from '../crypt/decrypter';\nimport AACDemuxer from './audio/aacdemuxer';\nimport MP4Demuxer from '../demux/mp4demuxer';\nimport TSDemuxer, { TypeSupported } from '../demux/tsdemuxer';\nimport MP3Demuxer from './audio/mp3demuxer';\nimport { AC3Demuxer } from './audio/ac3-demuxer';\nimport MP4Remuxer from '../remux/mp4-remuxer';\nimport PassThroughRemuxer from '../remux/passthrough-remuxer';\nimport { logger } from '../utils/logger';\nimport type { Demuxer, DemuxerResult, KeyData } from '../types/demuxer';\nimport type { Remuxer } from '../types/remuxer';\nimport type { TransmuxerResult, ChunkMetadata } from '../types/transmuxer';\nimport type { HlsConfig } from '../config';\nimport type { DecryptData } from '../loader/level-key';\nimport type { PlaylistLevelType } from '../types/loader';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\nimport { optionalSelf } from '../utils/global';\n\nlet now;\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  logger.debug('Unable to use Performance API on this environment');\n  now = optionalSelf?.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  public async: boolean = false;\n  private observer: HlsEventEmitter;\n  private typeSupported: TypeSupported;\n  private config: HlsConfig;\n  private vendor: string;\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  ) {\n    this.observer = observer;\n    this.typeSupported = typeSupported;\n    this.config = config;\n    this.vendor = vendor;\n    this.id = id;\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 && keyData.method === 'AES-128') {\n      const decrypter = this.getDecrypter();\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        );\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          decryptedData = decrypter.flush();\n        }\n        if (!decryptedData) {\n          stats.executeEnd = now();\n          return emptyResult(chunkMeta);\n        }\n        uintData = new Uint8Array(decryptedData);\n      } else {\n        this.decryptionPromise = decrypter\n          .webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer)\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        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    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      // 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, 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      return [emptyResult(chunkMeta)];\n    }\n\n    const demuxResultOrPromise = demuxer.flush(timeOffset);\n    if (isPromise(demuxResultOrPromise)) {\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    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    logger.log(\n      `[transmuxer.ts]: Flushed fragment ${chunkMeta.sn}${\n        chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''\n      } of level ${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, vendor } = 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)) {\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, vendor);\n    }\n    if (!demuxer || !(demuxer instanceof Demuxer)) {\n      this.demuxer = new Demuxer(observer, config, typeSupported);\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","'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","import Transmuxer, { isPromise } from '../demux/transmuxer';\nimport { Events } from '../events';\nimport { ILogFunction, enableLogs, logger } from '../utils/logger';\nimport { EventEmitter } from 'eventemitter3';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport type { RemuxedTrack, RemuxerResult } from '../types/remuxer';\nimport type { TransmuxerResult, ChunkMetadata } from '../types/transmuxer';\n\nif (typeof __IN_WORKER__ !== 'undefined' && __IN_WORKER__) {\n  startWorker(self);\n}\n\nfunction startWorker(self) {\n  const observer = new EventEmitter();\n  const forwardMessage = (ev, data) => {\n    self.postMessage({ event: ev, data: data });\n  };\n\n  // forward events to main thread\n  observer.on(Events.FRAG_DECRYPTED, forwardMessage);\n  observer.on(Events.ERROR, forwardMessage);\n\n  // forward logger events to main thread\n  const forwardWorkerLogs = () => {\n    for (const logFn in logger) {\n      const func: ILogFunction = (message?) => {\n        forwardMessage('workerLog', {\n          logType: logFn,\n          message,\n        });\n      };\n\n      logger[logFn] = func;\n    }\n  };\n\n  self.addEventListener('message', (ev) => {\n    const data = ev.data;\n    switch (data.cmd) {\n      case 'init': {\n        const config = JSON.parse(data.config);\n        self.transmuxer = new Transmuxer(\n          observer,\n          data.typeSupported,\n          config,\n          '',\n          data.id,\n        );\n        enableLogs(config.debug, data.id);\n        forwardWorkerLogs();\n        forwardMessage('init', null);\n        break;\n      }\n      case 'configure': {\n        self.transmuxer.configure(data.config);\n        break;\n      }\n      case 'demux': {\n        const transmuxResult: TransmuxerResult | Promise<TransmuxerResult> =\n          self.transmuxer.push(\n            data.data,\n            data.decryptdata,\n            data.chunkMeta,\n            data.state,\n          );\n        if (isPromise(transmuxResult)) {\n          self.transmuxer.async = true;\n          transmuxResult\n            .then((data) => {\n              emitTransmuxComplete(self, data);\n            })\n            .catch((error) => {\n              forwardMessage(Events.ERROR, {\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            });\n        } else {\n          self.transmuxer.async = false;\n          emitTransmuxComplete(self, transmuxResult);\n        }\n        break;\n      }\n      case 'flush': {\n        const id = data.chunkMeta;\n        let transmuxResult = self.transmuxer.flush(id);\n        const asyncFlush = isPromise(transmuxResult);\n        if (asyncFlush || self.transmuxer.async) {\n          if (!isPromise(transmuxResult)) {\n            transmuxResult = Promise.resolve(transmuxResult);\n          }\n          transmuxResult\n            .then((results: Array<TransmuxerResult>) => {\n              handleFlushResult(self, results as Array<TransmuxerResult>, id);\n            })\n            .catch((error) => {\n              forwardMessage(Events.ERROR, {\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            });\n        } else {\n          handleFlushResult(\n            self,\n            transmuxResult as Array<TransmuxerResult>,\n            id,\n          );\n        }\n        break;\n      }\n      default:\n        break;\n    }\n  });\n}\n\nfunction emitTransmuxComplete(\n  self: any,\n  transmuxResult: TransmuxerResult,\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 },\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) {\n  const parsed = results.reduce(\n    (parsed, result) => emitTransmuxComplete(self, result) || 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({ event: 'transmuxComplete', data: results[0] });\n  }\n  self.postMessage({ event: 'flush', data: chunkMeta });\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":["Events","ErrorTypes","ErrorDetails","AESCrypto","subtle","iv","this","aesIV","prototype","decrypt","data","key","name","FastAESKey","expandKey","importKey","sliceUint8","array","start","end","Uint8Array","slice","Array","call","AESDecryptor","rcon","subMix","Uint32Array","invSubMix","sBox","invSBox","ksRows","keySize","keySchedule","invKeySchedule","initTable","_proto","uint8ArrayToUint32Array_","arrayBuffer","view","DataView","newArray","i","getUint32","subMix0","subMix1","subMix2","subMix3","invSubMix0","invSubMix1","invSubMix2","invSubMix3","d","x","xi","sx","x2","x4","x8","t","keyBuffer","sameKey","offset","length","Error","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","buffer","noop","fakeLogger","trace","debug","log","warn","info","error","exportedLogger","exportLoggerFunctions","debugConfig","_len","arguments","functions","_key","forEach","type","bind","func","self","console","consolePrintFn","logger","isFiniteNumber","Number","isFinite","value","isSafeInteger","Math","abs","MAX_SAFE_INTEGER","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","substring","lastIndexOf","url","parts","split","reverse","join","replace","decoder","ElementaryStreamTypes","isHeader","isFooter","getID3Data","front","readSize","subarray","size","canParse","getTimeStamp","frames","getID3Frames","frame","isTimeStampFrame","readTimeStamp","getFrameData","String","fromCharCode","id3Data","frameData","decodeFrame","push","decodePrivFrame","decodeURLFrame","decodeTextFrame","owner","utf8ArrayToStr","privateData","index","description","text","timeStampFrame","byteLength","pts33Bit","timestamp","round","exitOnNull","getTextDecoder","decoded","decode","idx","indexOf","c","char2","char3","len","out","navigator","userAgent","includes","TextDecoder","Hex","str","h","toString","UINT32_MAX","pow","RemuxerTrackIdConfig","video","audio","id3","bin2str","apply","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","id","trex","track","default","flags","stsd","sampleEntries","sampleEntriesEnd","fourCC","codec","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","num","patchEncyptionData","decryptdata","keyId","isCommonEncryption","encBoxes","isAudio","enc","tenc","parseSinf","tencKeyId","some","b","set","computeRawDurationFromSamples","trun","sampleCount","appendUint8Array","data1","data2","temp","parseSamples","timeOffset","seiSamples","videoData","samples","isHEVCFlavor","map","moof","moofOffset","byteOffset","traf","baseTime","tfdt","undefined","tfhd","tfhdFlags","defaultSampleDuration","defaultSampleSizePresent","defaultSampleSize","defaultSampleFlagsPresent","tfhdOffset","delimit","baseCodec","isHEVC","dataOffsetPresent","dataOffset","firstSampleFlagsPresent","sampleDurationPresent","sampleDuration","sampleSizePresent","sampleSize","sampleFlagsPresent","sampleCompositionOffsetsPresent","compositionOffset","trunOffset","sampleOffset","ix","naluTotalSize","naluSize","isSEIMessage","parseSEIMessageFromNALu","naluHeader","naluType","unescapedData","headerSize","pts","discardEPB","seiPtr","payloadType","payloadSize","leftOver","payPtr","providerCode","userStructure","userDataType","enabled","totalBytes","byteArray","uuidStrArray","userDataBytes","uuid","userData","EPBPositions","newLength","newData","sourceIndex","shift","Decrypter","config","_temp","_ref$removePKCS7Paddi","removePKCS7Padding","logEnabled","softwareDecrypter","fastAesKey","remainderData","currentIV","currentResult","useSoftware","enableSoftwareAES","browserCrypto","crypto","webkitSubtle","e","destroy","isSync","flush","reset","outputBytes","paddingBytes","getUint8","_this","Promise","resolve","reject","softwareDecrypt","decryptResult","webCryptoDecrypt","logOnce","currentChunk","getValidChunk","_this2","onWebCryptoError","then","aesKey","catch","err","message","splitPoint","msg","MetadataSchema","dummyTrack","inputTimeScale","pid","sequenceNumber","dropped","BaseAudioDemuxer","_audioTrack","_id3Track","frameIndex","cachedData","basePTS","initPTS","lastPTS","resetInitSegment","audioCodec","videoCodec","trackDuration","resetTimeStamp","deaultTimestamp","resetContiguity","appendFrame","demux","lastDataIndex","ID3","id3Track","_isFiniteNumber","initPTSFn","dts","POSITIVE_INFINITY","sample","partialData","audioTrack","videoTrack","textTrack","demuxSampleAes","keyData","_isFiniteNumber2","isHeaderPattern","getHeaderLength","getFullFrameLength","probe","headerLength","frameLength","newOffset","initTrackConfig","observer","samplerate","adtsObjectType","adtsExtensionSamplingIndex","adtsChannelConfig","toLowerCase","manifestCodec","adtsSamplingRates","adtsSamplingIndex","test","channelCount","emit","ERROR","MEDIA_ERROR","details","FRAG_PARSING_ERROR","fatal","reason","getAudioConfig","getFrameDuration","unit","stamp","header","parseFrameHeader","missing","max","chromeVersion","BitratesMap","SamplingRateMap","SamplesCoefficients","BytesInSlot","parseHeader","samplesPerFrame","sampleRate","mpegVersion","mpegLayer","bitRateIndex","sampleRateIndex","paddingBit","channelMode","bitRate","sampleCoefficient","bytesInSlot","floor","match","parseInt","AACDemuxer","_BaseAudioDemuxer","_inheritsLoose","container","segmentCodec","MpegAudio","ADTS","canGetFrameLength","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","getAudioBSID","bsid","numBits","mask","bits","min","AC3Demuxer","samplingRateCode","frameSizeCode","skipCount","lfeon","bsmod","BaseVideoParser","VideoSample","createVideoSample","units","getLastNalUnit","_VideoSample","lastUnit","pushAccessUnit","nbSamples","lastSample","ExpGolomb","bytesAvailable","bitsAvailable","loadWord","position","workingBytes","availableBytes","skipBits","count","skipBytes","readBits","valu","skipLZ","leadingZeroCount","skipUEG","skipEG","readUEG","clz","readEG","readBoolean","readUByte","readUShort","readUInt","skipScalingList","lastScale","nextScale","j","readSPS","numRefFramesInPicOrderCntCycle","scalingListCount","frameCropLeftOffset","frameCropRightOffset","frameCropTopOffset","frameCropBottomOffset","profileIdc","chromaFormatIdc","picOrderCntType","picWidthInMbsMinus1","picHeightInMapUnitsMinus1","frameMbsOnlyFlag","pixelRatio","width","ceil","height","readSliceType","AvcVideoParser","_BaseVideoParser","parseAVCPES","pes","parseAVCNALu","spsfound","audFound","_VideoSample2","iskey","sliceType","_track$pixelRatio","_track$pixelRatio2","sps","codecarray","codecstring","pps","overflow","state","naluState","lastState","lastUnitStart","lastUnitType","SampleAesDecrypter","decrypter","decryptBuffer","encryptedData","decryptAacSample","sampleIndex","callback","curUnit","encryptedBuffer","decryptedBuffer","decryptedData","decryptAacSamples","getAvcEncryptedData","decodedData","encryptedDataLen","Int8Array","outputPos","inputPos","getAvcDecryptedUnit","uint8DecryptedData","decryptAvcSample","unitIndex","decryptAvcSamples","curUnits","PACKET_LENGTH","TSDemuxer","typeSupported","sampleAes","pmtParsed","_duration","_pmtId","_videoTrack","_txtTrack","aacOverFlow","videoParser","syncOffset","scanwindow","foundPat","packetStart","tsPackets","parsePID","createTrack","pesData","isSampleAes","videoPid","audioPid","id3Pid","audioData","unknownPID","pmtId","tsPacketErrors","stt","parsePES","parseAACPES","parseMPEGPES","parseAC3PES","parseID3PES","parsePAT","parsedPIDs","parsePMT","segmentVideoCodec","segmentAudioCodec","emitParsingError","demuxResult","extractRemainingSamples","startOffset","frameMissingBytes","sampleLength","frameOverflowBytes","recoverable","frameDuration","parsed","AC3","id3Sample","_extends","tableEnd","esInfoLength","logEncryptedSamplesFoundInUnencryptedStream","mpeg","mp3","ac3","parsePos","remaining","descriptorLen","levelRetry","stream","frag","pesLen","pesHdrLen","pesPts","pesDts","splice","pesFlags","payloadStartOffset","dataLen","MP3Demuxer","AAC","getSilentFrame","MP4","init","types","avc1","avcC","btrt","dinf","dref","esds","ftyp","mdat","mdia","mfhd","minf","moov","mp4a","dac3","mvex","mvhd","pasp","sdtp","stbl","stco","stsc","stsz","stts","vmhd","smhd","hasOwnProperty","charCodeAt","videoHdlr","audioHdlr","HDLR_TYPES","STTS","STSC","STCO","STSZ","VMHD","SMHD","STSD","majorBrand","avc1Brand","minorVersion","FTYP","box","DINF","upperWordDuration","lowerWordDuration","sn","baseMediaDecodeTime","tracks","boxes","concat","dependsOn","isDependedOn","hasRedundancy","avcc","hSpacing","vSpacing","configlen","audioStsd","sampleDependencyTable","upperWordBaseMediaDecodeTime","lowerWordBaseMediaDecodeTime","cts","arraylen","isLeading","paddingValue","isNonSync","degradPrio","movie","PlaylistLevelType","toMsFromMpegTsClock","destScale","srcBase","toTimescaleFromBase","safariWebkitVersion","MP4Remuxer","vendor","ISGenerated","_initPTS","_initDTS","nextAvcDts","nextAudioPts","videoSampleDuration","isAudioContiguous","isVideoContiguous","videoTrackConfig","defaultTimeStamp","resetNextTimestamp","getVideoStartPts","rolloverDetected","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","Infinity","metadata","Object","keys","contiguous","firstDTS","lastDTS","inputSamples","outputSamples","mp4SampleDuration","maxPTS","NEGATIVE_INFINITY","sortSamples","initTime","sort","a","deltadts","deltapts","inputDuration","averageSampleDuration","foundHole","foundOverlap","toFixed","firstPTS","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","Mp4Sample","nextDts","nextPts","startDTS","endDTS","nb","getSamplesPerFrame","scaleFactor","inputSampleDuration","rawMPEG","alignedWithVideo","timeOffsetMpegTS","filter","maxAudioFramesDrift","newStamp","fillFrame","audioSample","unitLen","remuxEmptyAudio","init90kHz","silentFrame","reference","isKeyframe","isCodecMediaSourceSupported","preferManagedMediaSource","_MediaSource$isTypeSu","MediaSource","ManagedMediaSource","WebKitMediaSource","getMediaSource","isTypeSupported","mimeTypeForCodec","CODEC_COMPATIBLE_NAMES","AUDIO_CODEC_REGEXP","getCodecCompatibleName","m","lowerCaseCodec","codecsToCheck","flac","opus","getCodecCompatibleNameLower","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","parsedCodec","now","optionalSelf","performance","Date","muxConfig","Transmuxer","async","demuxer","remuxer","decryptionPromise","transmuxConfig","currentTransmuxState","configure","chunkMeta","stats","transmuxing","executeStart","uintData","_ref","discontinuity","trackSwitch","initSegmentChange","defaultInitPts","initSegmentData","decryptData","encryptionType","method","getEncryptionType","getDecrypter","part","executeEnd","emptyResult","resetMuxers","needsProbing","configureTransmuxer","resetInitialTimestamp","transmux","currentState","transmuxResults","demuxResultOrPromise","isPromise","flushRemux","_this$currentTransmux","remuxResult","transmuxSampleAes","transmuxUnencrypted","_demux","_this3","mux","_muxConfig$i$demux","Remuxer","Demuxer","p","Function","has","prefix","EE","fn","context","once","addListener","emitter","event","TypeError","listener","evt","_events","_eventsCount","clearEvent","EventEmitter","create","__proto__","eventNames","events","names","getOwnPropertySymbols","listeners","handlers","l","ee","listenerCount","a1","a2","a3","a4","a5","args","removeListener","on","removeAllListeners","off","prefixed","module","exports","emitTransmuxComplete","transmuxResult","transferable","_transmuxResult$remux","addToTransferable","postMessage","handleFlushResult","forwardMessage","ev","FRAG_DECRYPTED","forwardWorkerLogs","_loop","logFn","logType","addEventListener","cmd","JSON","parse","transmuxer","enableLogs","startWorker"],"mappings":"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ACNC,KAAM,GACNjb,KAAM,GACNkb,KAAM,GACNC,KAAM,GACN,OAAQ,GACRC,KAAM,GACN,OAAQ,GACRC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNngB,KAAM,GACNogB,KAAM,GACNC,KAAM,GACNxb,KAAM,GACNE,KAAM,GACNJ,KAAM,GACN3F,KAAM,GACN2E,KAAM,GACN/D,KAAM,GACNX,KAAM,GACNqhB,KAAM,GACNC,KAAM,IAIE3B,EAAIE,MACRF,EAAIE,MAAM0B,eAAe7uB,KAC3BitB,EAAIE,MAAMntB,GAAK,CACbA,EAAE8uB,WAAW,GACb9uB,EAAE8uB,WAAW,GACb9uB,EAAE8uB,WAAW,GACb9uB,EAAE8uB,WAAW,KAKnB,IAAMC,EAAY,IAAIrwB,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,IAGIswB,EAAY,IAAItwB,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,IAGFuuB,EAAIgC,WAAa,CACf7jB,MAAO2jB,EACP1jB,MAAO2jB,GAGT,IAAMxB,EAAO,IAAI9uB,WAAW,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,GACA,EACA,EACA,EACA,IAGI6vB,EAAO,IAAI7vB,WAAW,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IAGFuuB,EAAIiC,KAAOjC,EAAIkC,KAAOlC,EAAImC,KAAOb,EAEjCtB,EAAIoC,KAAO,IAAI3wB,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UAAUa,MAAME,KAAKb,IAI9C,IAAKgC,EAAI,EAAGA,EAAIkO,EAAMsY,IAAInlB,OAAQrB,IAEhCuK,GADAvM,EAAOkQ,EAAMsY,IAAIxmB,IACN0J,WACX8c,EAAIzd,KAAMwB,IAAQ,EAAK,KACvBic,EAAIzd,KAAW,IAANwB,GAETic,EAAMA,EAAI6J,OAAOzxB,MAAMd,UAAUa,MAAME,KAAKb,IAG9C,IAAMyyB,EAAOxD,EAAI4C,IACf5C,EAAIE,MAAME,KACV,IAAI3uB,WACF,CACE,EACA2nB,EAAI,GACJA,EAAI,GACJA,EAAI,GACJ,IACA,IAAOnY,EAAMmY,IAAIhlB,QAEhBgvB,OAAOhK,GACPgK,OAAO,CACNniB,EAAMsY,IAAInlB,SAEXgvB,OAAO7J,KAGRnB,EAAQnX,EAAMmX,MACdE,EAASrX,EAAMqX,OACfmL,EAAWxiB,EAAMkX,WAAW,GAC5BuL,EAAWziB,EAAMkX,WAAW,GAElC,OAAO6H,EAAI4C,IACT5C,EAAIE,MAAMC,KACV,IAAI1uB,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,EACC2mB,GAAS,EAAK,IACP,IAARA,EACCE,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,KAEFkL,EACAxD,EAAI4C,IACF5C,EAAIE,MAAMG,KACV,IAAI5uB,WAAW,CACb,EACA,GACA,IACA,IACA,EACA,GACA,IACA,IACA,EACA,GACA,IACA,OAGJuuB,EAAI4C,IACF5C,EAAIE,MAAMiB,KACV,IAAI1vB,WAAW,CACbgyB,GAAY,GACXA,GAAY,GAAM,IAClBA,GAAY,EAAK,IACP,IAAXA,EACAC,GAAY,GACXA,GAAY,GAAM,IAClBA,GAAY,EAAK,IACP,IAAXA,OAIP1D,EAEMQ,KAAP,SAAYvf,GACV,IAAM0iB,EAAY1iB,EAAMwI,OAAOrV,OAC/B,OAAO,IAAI3C,WACT,CACE,EACA,EACA,EACA,EAEA,EACA,GAAOkyB,EACP,EACA,EACA,EAEA,EACA,GAAOA,EACP,GACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EAEA,GAECP,OAAO,CAACO,IACRP,OAAOniB,EAAMwI,QACb2Z,OAAO,CAAC,EAAM,EAAM,MAE1BpD,EAEM4D,UAAP,SAAiB3iB,GACf,IAAMiO,EAAajO,EAAMiO,WACzB,OAAO,IAAIzd,WAAW,CACpB,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACAwP,EAAM0O,aACN,EACA,GACA,EACA,EACA,EACA,EACCT,GAAc,EAAK,IACP,IAAbA,EACA,EACA,KAEH8Q,EAEMe,KAAP,SAAY9f,GACV,OAAO+e,EAAI4C,IACT5C,EAAIE,MAAMa,KACVf,EAAI4D,UAAU3iB,GACd+e,EAAI4C,IAAI5C,EAAIE,MAAMM,KAAMR,EAAIQ,KAAKvf,MAEpC+e,EAEMnB,IAAP,SAAW5d,GACT,OAAO+e,EAAI4C,IAAI5C,EAAIE,MAAM,QAASF,EAAI4D,UAAU3iB,KACjD+e,EAEMlB,IAAP,SAAW7d,GACT,OAAO+e,EAAI4C,IACT5C,EAAIE,MAAM,QACVF,EAAI4D,UAAU3iB,GACd+e,EAAI4C,IAAI5C,EAAIE,MAAMc,KAAM/f,EAAMwI,UAEjCuW,EAEM5e,KAAP,SAAYH,GACV,MAAmB,UAAfA,EAAM5J,KACmB,QAAvB4J,EAAMkR,cAA0C,QAAhBlR,EAAMO,MACjCwe,EAAI4C,IAAI5C,EAAIE,MAAM9e,KAAM4e,EAAIuC,KAAMvC,EAAInB,IAAI5d,IAExB,QAAvBA,EAAMkR,aACD6N,EAAI4C,IAAI5C,EAAIE,MAAM9e,KAAM4e,EAAIuC,KAAMvC,EAAIlB,IAAI7d,IAE5C+e,EAAI4C,IAAI5C,EAAIE,MAAM9e,KAAM4e,EAAIuC,KAAMvC,EAAIe,KAAK9f,IAE3C+e,EAAI4C,IAAI5C,EAAIE,MAAM9e,KAAM4e,EAAIuC,KAAMvC,EAAIG,KAAKlf,KAErD+e,EAEM3f,KAAP,SAAYY,GACV,IAAMF,EAAKE,EAAMF,GACXf,EAAWiB,EAAMjB,SAAWiB,EAAM1B,UAClC6Y,EAAQnX,EAAMmX,MACdE,EAASrX,EAAMqX,OACfwK,EAAoB7qB,KAAK2Z,MAAM5R,GAAYhC,GAAa,IACxD+kB,EAAoB9qB,KAAK2Z,MAAM5R,GAAYhC,GAAa,IAC9D,OAAOgiB,EAAI4C,IACT5C,EAAIE,MAAM7f,KACV,IAAI5O,WAAW,CACb,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACCsP,GAAM,GAAM,IACZA,GAAM,GAAM,IACZA,GAAM,EAAK,IACP,IAALA,EACA,EACA,EACA,EACA,EACA+hB,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,EACC3K,GAAS,EAAK,IACP,IAARA,EACA,EACA,EACCE,GAAU,EAAK,IACP,IAATA,EACA,EACA,MAGL0H,EAEMja,KAAP,SAAY9E,EAAOgiB,GACjB,IAAMY,EAAwB7D,EAAIoB,KAAKngB,GACjCF,EAAKE,EAAMF,GACX+iB,EAA+B7rB,KAAK2Z,MACxCqR,GAAuBjlB,GA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","x_google_ignoreList":[8,39]}