friendica-github/view/js/hls/hls.worker.js.map
2024-09-14 18:06:59 +00:00

1 line
No EOL
472 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"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]}