{"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/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(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n once(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n\n removeAllListeners(event?: E): void;\n off(\n event: E,\n listener?: HlsListeners[E],\n context?: Context,\n once?: boolean,\n ): void;\n\n listeners(event: E): HlsListeners[E][];\n emit(\n event: E,\n name: E,\n eventObject: Parameters[1],\n ): boolean;\n listenerCount(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: any;\n private key: ArrayBuffer;\n\n constructor(subtle, key) {\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 = [\n 0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,\n ];\n private subMix: Array = [\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n ];\n private invSubMix: Array = [\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 (self.console && 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","export const isFiniteNumber =\n Number.isFinite ||\n function (value) {\n return typeof value === 'number' && isFinite(value);\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 is non-empty, we skip to\n // Step 7. Otherwise, the embedded URL inherits the \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 is non-empty, we skip to\n // step 7; otherwise, it inherits the of the base\n // URL (if any) and\n if (!relativeParts.params) {\n builtParts.params = baseParts.params;\n // 5b) if the embedded URL's is non-empty, we skip to\n // step 7; otherwise, it inherits the 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 \"/../\", where 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 \"/..\", where is a\n // complete path segment not equal to \"..\", that\n // \"/..\" 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 = [];\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 | 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 | 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 public urlId: number = 0;\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\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 = { key: string; data: T; info?: any };\nexport type Frame = DecodedFrame;\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);\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 | undefined => {\n /*\n Format: \\0\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 | 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 | 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,\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 \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 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 { 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 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 // TODO: parse earliestPresentationTime and firstOffset\n // usually zero in our case\n const earliestPresentationTime = 0;\n const firstOffset = 0;\n\n if (version === 0) {\n index += 8;\n } else {\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 {\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 // profile + compatibility + level\n codec += '.' + toHex(stsd[111]) + toHex(stsd[112]) + toHex(stsd[113]);\n break;\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 && esdsBox[11] !== 0) {\n codec += '.' + toHex(esdsBox[11]);\n codec += '.' + ((esdsBox[12] >>> 2) & 0x3f).toString(16).toUpperCase();\n }\n break;\n }\n // break;\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 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 logger.error(`[eme] missing 'schm' box`);\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 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 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 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 sidxDuration += sidx.references.reduce(\n (dur, ref) => dur + ref.info.duration || 0,\n 0,\n );\n }\n }\n\n return sidxDuration;\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 endOfCaptions = false;\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\n if (!endOfCaptions && payloadType === 4 && seiPtr < data.length) {\n endOfCaptions = true;\n\n const countryCode = data[seiPtr++];\n if (countryCode === 181) {\n const providerCode = readUint16(data, seiPtr);\n seiPtr += 2;\n\n if (providerCode === 49) {\n const userStructure = readUint32(data, seiPtr);\n seiPtr += 4;\n\n if (userStructure === 0x47413934) {\n const userDataType = data[seiPtr++];\n\n // Raw CEA-608 bytes wrapped in CEA-708 packet\n if (userDataType === 3) {\n const firstByte = data[seiPtr++];\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[seiPtr++];\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 && payloadSize < leftOver) {\n endOfCaptions = true;\n\n if (payloadSize > 16) {\n const uuidStrArray: Array = [];\n for (let i = 0; i < 16; i++) {\n const b = data[seiPtr++].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[seiPtr++];\n }\n\n samples.push({\n payloadType,\n pts,\n uuid: uuidStrArray.join(''),\n userData: utf8ArrayToStr(userDataBytes),\n userDataBytes,\n });\n }\n } else if (payloadSize < leftOver) {\n seiPtr += payloadSize;\n } else if (payloadSize > leftOver) {\n break;\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;\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, ...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 | 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 function parsePssh(initData: ArrayBuffer) {\n if (!(initData instanceof ArrayBuffer) || initData.byteLength < 32) {\n return null;\n }\n const result = {\n version: 0,\n systemId: '',\n kids: null as null | Uint8Array[],\n data: null as null | Uint8Array,\n };\n const view = new DataView(initData);\n const boxSize = view.getUint32(0);\n if (initData.byteLength !== boxSize && boxSize > 44) {\n return null;\n }\n const type = view.getUint32(4);\n if (type !== 0x70737368) {\n return null;\n }\n result.version = view.getUint32(8) >>> 24;\n if (result.version > 1) {\n return null;\n }\n result.systemId = Hex.hexDump(new Uint8Array(initData, 12, 16));\n const dataSizeOrKidCount = view.getUint32(28);\n if (result.version === 0) {\n if (boxSize - 32 < dataSizeOrKidCount) {\n return null;\n }\n result.data = new Uint8Array(initData, 32, dataSizeOrKidCount);\n } else if (result.version === 1) {\n result.kids = [];\n for (let i = 0; i < dataSizeOrKidCount; i++) {\n result.kids.push(new Uint8Array(initData, 32 + i * 16, 16));\n }\n }\n return result;\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 if (this.subtle === null) {\n this.useSoftware = true;\n }\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 {\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 {\n const subtle = this.subtle;\n if (this.key !== key || !this.fastAesKey) {\n this.key = key;\n this.fastAesKey = new FastAESKey(subtle, key);\n }\n return this.fastAesKey\n .expandKey()\n .then((aesKey) => {\n // decrypt using web crypto\n if (!subtle) {\n return Promise.reject(new Error('web crypto not initialized'));\n }\n this.logOnce('WebCrypto AES decrypt');\n const crypto = new AESCrypto(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(data, key, iv): 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;\n flush(timeOffset?: number): DemuxerResult | Promise;\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 {\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 *

\n * use timestamp unless it is undefined, NaN or Infinity\n *

\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 {\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 {\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 | 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;\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 );\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 const error = new Error(\n `Found ${tsPacketErrors} TS packet/s that do not start with 0x47`,\n );\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 }\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 {\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 {\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 {\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 const error = new Error(reason);\n logger.warn(`parsing error: ${reason}`);\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: false,\n levelRetry: recoverable,\n error,\n reason,\n });\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, {\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) {\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 logger.warn('Unsupported EC-3 in M2TS found');\n break;\n case 0x24:\n logger.warn('Unsupported HEVC in M2TS found');\n break;\n\n default:\n // logger.log('unknown stream type:' + data[offset]);\n break;\n }\n // move to the next table entry\n // skip past the elementary stream descriptors, if present\n offset += esInfoLength + 5;\n }\n return result;\n}\n\nfunction 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;\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;\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 = (\n response: LoaderResponse,\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnProgress = (\n stats: LoaderStats,\n context: T,\n data: string | ArrayBuffer,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnError = (\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 = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnAbort = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport interface LoaderCallbacks {\n onSuccess: LoaderOnSuccess;\n onError: LoaderOnError;\n onTimeout: LoaderOnTimeout;\n onAbort?: LoaderOnAbort;\n onProgress?: LoaderOnProgress;\n}\n\nexport interface Loader {\n destroy(): void;\n abort(): void;\n load(\n context: T,\n config: LoaderConfiguration,\n callbacks: LoaderCallbacks,\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 // track group id\n groupId?: 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 = track.samples;\n const outputSamples: Array = [];\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 = [];\n const alignedWithVideo = videoTimeOffset !== undefined;\n\n let inputSamples: Array = 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 = [];\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): 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 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;\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","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","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';\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 = typeof self !== 'undefined' && self.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 | 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 {\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 {\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 {\n let result: TransmuxerResult | Promise;\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 {\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 != null &&\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(p: Promise | any): p is Promise {\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 data.vendor,\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 =\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) => {\n handleFlushResult(self, results as Array, 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,\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 = [];\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,\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,\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","enableLogs","id","e","logger","isFiniteNumber","Number","isFinite","value","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","Math","round","exitOnNull","getTextDecoder","decoded","decode","idx","indexOf","c","char2","char3","len","out","TextDecoder","Hex","str","h","toString","UINT32_MAX","pow","RemuxerTrackIdConfig","video","audio","id3","bin2str","apply","readUint16","val","readUint32","readSint32","writeUint32","findBox","results","endbox","subresults","parseSegmentIndex","sidx","references","version","timescale","startByte","referencesCount","referenceIndex","referenceInfo","referenceSize","subsegmentDuration","duration","earliestPresentationTime","parseInitSegment","initSegment","result","traks","trak","tkhd","trackId","mdhd","hdlr","hdlrType","soun","vide","stsdData","parseStsd","_objectSpread","trex","track","default","flags","stsd","sampleEntries","sampleEntriesEnd","fourCC","codec","encrypted","encBox","sinf","schm","frma","toHex","codecBox","esdsBox","toUpperCase","hvcCBox","profileByte","profileSpace","generalProfileIdc","profileCompat","tierFlag","levelIDC","constraintIndicator","constraintString","byte","dvcCBox","profile","level","addLeadingZero","vpcCBox","bitDepth","av1CBox","highBitDepth","twelveBit","monochrome","chromaSubsamplingX","chromaSubsamplingY","chromaSamplePosition","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","endOfCaptions","leftOver","providerCode","userStructure","userDataType","firstByte","enabled","totalBytes","byteArray","bytes","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","destroy","isSync","flush","reset","outputBytes","paddingBytes","getUint8","_this","Promise","resolve","reject","softwareDecrypt","decryptResult","webCryptoDecrypt","logOnce","currentChunk","getValidChunk","_this2","then","aesKey","catch","err","message","onWebCryptoError","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","userAgent","navigator","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","MAX_SAFE_INTEGER","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","demuxResult","extractRemainingSamples","startOffset","frameMissingBytes","sampleLength","frameOverflowBytes","recoverable","levelRetry","frameDuration","parsed","AC3","id3Sample","_extends","tableEnd","esInfoLength","logEncryptedSamplesFoundInUnencryptedStream","mpeg","mp3","ac3","parsePos","remaining","descriptorLen","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","abs","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","now","PassThroughRemuxer","emitInitSegment","initTracks","lastEndTime","defaultInitPTS","generateInitSegment","getParsedTrackCodec","audiovideo","_initData","_initData2","rawDuration","videoDuration","audioDuration","trafs","trackDefault","truns","sidxDuration","sidxs","dur","ref","getDuration","fmp4","startTime","getStartDTS","decodeTime","minDuration","isInvalidInitPts","endTime","upper","lower","offsetStartDTS","parsedCodec","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","startWorker"],"mappings":"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AAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAC5D,GAAM,IAGV,GAGL2tB,CAAA,CAzEM,GCOHvhB,GAAalB,KAAKmB,IAAI,EAAG,IAAM,EAE/BwhB,GAAG,WAAA,SAAAA,IAAA,CAulCN,OAvlCMA,EAaAC,KAAP,WA0CE,IAAIxsB,EACJ,IAAKA,KA1CLusB,EAAIE,MAAQ,CACVC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACN5f,KAAM,GACN6f,KAAM,GACN9f,KAAM,GACN+f,KAAM,GACNC,KAAM,GACNC,KAAM,GACNpb,KAAM,GACNqb,KAAM,GACNC,KAAM,GACN,OAAQ,GACRC,KAAM,GACN,OAAQ,GACRC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACN/f,KAAM,GACNggB,KAAM,GACNC,KAAM,GACN3b,KAAM,GACNE,KAAM,GACNJ,KAAM,GACNnF,KAAM,GACNmE,KAAM,GACNxD,KAAM,GACNV,KAAM,GACNghB,KAAM,GACNC,KAAM,IAIE3B,EAAIE,MACRF,EAAIE,MAAM0B,eAAenuB,KAC3BusB,EAAIE,MAAMzsB,GAAK,CACbA,EAAEouB,WAAW,GACbpuB,EAAEouB,WAAW,GACbpuB,EAAEouB,WAAW,GACbpuB,EAAEouB,WAAW,KAKnB,IAAMC,EAAY,IAAI3vB,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,IAGI4vB,EAAY,IAAI5vB,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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A,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,KAEFiL,EACAxD,EAAI4C,IACF5C,EAAIE,MAAMG,KACV,IAAIluB,WAAW,CACb,EACA,GACA,IACA,IACA,EACA,GACA,IACA,IACA,EACA,GACA,IACA,OAGJ6tB,EAAI4C,IACF5C,EAAIE,MAAMiB,KACV,IAAIhvB,WAAW,CACbsxB,GAAY,GACXA,GAAY,GAAM,IAClBA,GAAY,EAAK,IACP,IAAXA,EACAC,GAAY,GACXA,GAAY,GAAM,IAClBA,GAAY,EAAK,IACP,IAAXA,OAIP1D,EAEMQ,KAAP,SAAYnf,GACV,IAAMsiB,EAAYtiB,EAAMmI,OAAO1U,OAC/B,OAAO,IAAI3C,WACT,CACE,EACA,EACA,EACA,EAEA,EACA,GAAOwxB,EACP,EACA,EACA,EAEA,EACA,GAAOA,EACP,GACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EAEA,GAECP,OAAO,CAACO,IACRP,OAAO/hB,EAAMmI,QACb4Z,OAAO,CAAC,EAAM,EAAM,MAE1BpD,EAEM4D,UAAP,SAAiBviB,GACf,IAAM2N,EAAa3N,EAAM2N,WACzB,OAAO,IAAI7c,WAAW,CACpB,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACAkP,EAAMsO,aACN,EACA,GACA,EACA,EACA,EACA,EACCX,GAAc,EAAK,IACP,IAAbA,EACA,EACA,KAEHgR,EAEMe,KAAP,SAAY1f,GACV,OAAO2e,EAAI4C,IACT5C,EAAIE,MAAMa,KACVf,EAAI4D,UAAUviB,GACd2e,EAAI4C,IAAI5C,EAAIE,MAAMM,KAAMR,EAAIQ,KAAKnf,MAEpC2e,EAEMlB,IAAP,SAAWzd,GACT,OAAO2e,EAAI4C,IAAI5C,EAAIE,MAAM,QAASF,EAAI4D,UAAUviB,KACjD2e,EAEMjB,IA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","x_google_ignoreList":[8,38]}