hls.js
Version:
JavaScript HLS client using MediaSourceExtension
1 lines • 2.01 MB
Source Map (JSON)
{"version":3,"file":"hls.light.mjs.map","sources":["src/polyfills/number.ts","src/errors.ts","src/events.ts","src/types/loader.ts","src/utils/ewma.ts","src/utils/ewma-bandwidth-estimator.ts","src/utils/logger.ts","src/empty-es.js","src/utils/mediasource-helper.ts","node_modules/@svta/common-media-library/dist/utils/utf8ArrayToStr.js","src/utils/hex.ts","node_modules/url-toolkit/src/url-toolkit.js","src/loader/load-stats.ts","src/loader/fragment.ts","src/utils/mp4-tools.ts","src/utils/codecs.ts","src/types/level.ts","src/utils/hdr.ts","src/utils/safe-json-stringify.ts","src/utils/rendition-helper.ts","src/controller/abr-controller.ts","src/utils/binary-search.ts","src/controller/fragment-finders.ts","src/utils/error-helper.ts","src/controller/error-controller.ts","src/utils/attr-list.ts","src/loader/date-range.ts","src/loader/level-details.ts","src/utils/arrays.ts","src/crypt/decrypter-aes-mode.ts","src/utils/encryption-methods-util.ts","src/loader/level-key.ts","src/loader/m3u8-parser.ts","src/utils/level-helper.ts","src/controller/base-playlist-controller.ts","src/controller/fragment-tracker.ts","src/crypt/aes-crypto.ts","src/crypt/aes-decryptor.ts","src/crypt/fast-aes-key.ts","src/crypt/decrypter.ts","src/loader/fragment-loader.ts","src/task-loop.ts","src/types/transmuxer.ts","src/utils/buffer-helper.ts","src/utils/discontinuities.ts","src/utils/event-listener-helper.ts","src/utils/time-ranges.ts","src/controller/base-stream-controller.ts","src/controller/buffer-operation-queue.ts","src/controller/buffer-controller.ts","src/controller/cap-level-controller.ts","src/controller/content-steering-controller.ts","src/controller/fps-controller.ts","node_modules/@svta/common-media-library/dist/utils/uuid.js","node_modules/eventemitter3/index.js","src/demux/chunk-cache.ts","node_modules/@svta/common-media-library/dist/id3/util/isId3Footer.js","node_modules/@svta/common-media-library/dist/id3/util/isId3Header.js","node_modules/@svta/common-media-library/dist/id3/util/readId3Size.js","node_modules/@svta/common-media-library/dist/id3/getId3Data.js","src/demux/audio/adts.ts","node_modules/@svta/common-media-library/dist/id3/canParseId3.js","node_modules/@svta/common-media-library/dist/id3/util/toArrayBuffer.js","node_modules/@svta/common-media-library/dist/id3/util/utf8.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3ImageFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3PrivFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3TextFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3UrlFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3Frame.js","node_modules/@svta/common-media-library/dist/id3/util/getId3FrameData.js","node_modules/@svta/common-media-library/dist/id3/getId3Frames.js","node_modules/@svta/common-media-library/dist/id3/isId3TimestampFrame.js","node_modules/@svta/common-media-library/dist/id3/util/readId3Timestamp.js","node_modules/@svta/common-media-library/dist/id3/getId3Timestamp.js","src/types/demuxer.ts","src/demux/dummy-demuxed-track.ts","src/demux/audio/base-audio-demuxer.ts","src/demux/audio/mpegaudio.ts","src/demux/audio/aacdemuxer.ts","src/demux/audio/dolby.ts","src/demux/audio/mp3demuxer.ts","src/demux/mp4demuxer.ts","src/demux/sample-aes.ts","src/demux/video/base-video-parser.ts","src/demux/video/exp-golomb.ts","src/demux/video/avc-video-parser.ts","src/demux/tsdemuxer.ts","src/remux/aac-helper.ts","src/remux/mp4-generator.ts","src/utils/timescale-conversion.ts","src/remux/mp4-remuxer.ts","src/remux/passthrough-remuxer.ts","src/demux/transmuxer.ts","src/utils/fetch-loader.ts","src/utils/xhr-loader.ts","src/config.ts","src/controller/gap-controller.ts","src/utils/texttrack-utils.ts","src/controller/id3-track-controller.ts","src/controller/latency-controller.ts","src/controller/level-controller.ts","src/version.ts","src/demux/inject-worker.ts","src/demux/transmuxer-interface.ts","src/is-supported.ts","src/controller/stream-controller.ts","src/loader/key-loader.ts","src/loader/playlist-loader.ts","src/utils/mediacapabilities-helper.ts","src/hls.ts"],"sourcesContent":["// https://caniuse.com/mdn-javascript_builtins_number_isfinite\nexport const isFiniteNumber =\n Number.isFinite ||\n function (value) {\n return typeof value === 'number' && isFinite(value);\n };\n\n// https://caniuse.com/mdn-javascript_builtins_number_issafeinteger\nexport const isSafeInteger =\n Number.isSafeInteger ||\n function (value) {\n return typeof value === 'number' && Math.abs(value) <= MAX_SAFE_INTEGER;\n };\n\nexport const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;\n","export enum ErrorTypes {\n // Identifier for a network error (loading error / timeout ...)\n NETWORK_ERROR = 'networkError',\n // Identifier for a media Error (video/parsing/mediasource error)\n MEDIA_ERROR = 'mediaError',\n // EME (encrypted media extensions) errors\n KEY_SYSTEM_ERROR = 'keySystemError',\n // Identifier for a mux Error (demuxing/remuxing)\n MUX_ERROR = 'muxError',\n // Identifier for all other errors\n OTHER_ERROR = 'otherError',\n}\n\nexport enum ErrorDetails {\n KEY_SYSTEM_NO_KEYS = 'keySystemNoKeys',\n KEY_SYSTEM_NO_ACCESS = 'keySystemNoAccess',\n KEY_SYSTEM_NO_SESSION = 'keySystemNoSession',\n KEY_SYSTEM_NO_CONFIGURED_LICENSE = 'keySystemNoConfiguredLicense',\n KEY_SYSTEM_LICENSE_REQUEST_FAILED = 'keySystemLicenseRequestFailed',\n KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED = 'keySystemServerCertificateRequestFailed',\n KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED = 'keySystemServerCertificateUpdateFailed',\n KEY_SYSTEM_SESSION_UPDATE_FAILED = 'keySystemSessionUpdateFailed',\n KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED = 'keySystemStatusOutputRestricted',\n KEY_SYSTEM_STATUS_INTERNAL_ERROR = 'keySystemStatusInternalError',\n KEY_SYSTEM_DESTROY_MEDIA_KEYS_ERROR = 'keySystemDestroyMediaKeysError',\n KEY_SYSTEM_DESTROY_CLOSE_SESSION_ERROR = 'keySystemDestroyCloseSessionError',\n KEY_SYSTEM_DESTROY_REMOVE_SESSION_ERROR = 'keySystemDestroyRemoveSessionError',\n // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n MANIFEST_LOAD_ERROR = 'manifestLoadError',\n // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n MANIFEST_LOAD_TIMEOUT = 'manifestLoadTimeOut',\n // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}\n MANIFEST_PARSING_ERROR = 'manifestParsingError',\n // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}\n MANIFEST_INCOMPATIBLE_CODECS_ERROR = 'manifestIncompatibleCodecsError',\n // Identifier for a level which contains no fragments - data: { url: faulty URL, reason: \"no fragments found in level\", level: index of the bad level }\n LEVEL_EMPTY_ERROR = 'levelEmptyError',\n // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n LEVEL_LOAD_ERROR = 'levelLoadError',\n // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n LEVEL_LOAD_TIMEOUT = 'levelLoadTimeOut',\n // Identifier for a level parse error - data: { url : faulty URL, error: Error, reason: error message }\n LEVEL_PARSING_ERROR = 'levelParsingError',\n // Identifier for a level switch error - data: { level : faulty level Id, event : error description}\n LEVEL_SWITCH_ERROR = 'levelSwitchError',\n // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n AUDIO_TRACK_LOAD_ERROR = 'audioTrackLoadError',\n // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n AUDIO_TRACK_LOAD_TIMEOUT = 'audioTrackLoadTimeOut',\n // Identifier for a subtitle track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n SUBTITLE_LOAD_ERROR = 'subtitleTrackLoadError',\n // Identifier for a subtitle track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n SUBTITLE_TRACK_LOAD_TIMEOUT = 'subtitleTrackLoadTimeOut',\n // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n FRAG_LOAD_ERROR = 'fragLoadError',\n // Identifier for fragment load timeout error - data: { frag : fragment object}\n FRAG_LOAD_TIMEOUT = 'fragLoadTimeOut',\n // Identifier for a fragment decryption error event - data: {id : demuxer Id,frag: fragment object, reason : parsing error description }\n FRAG_DECRYPT_ERROR = 'fragDecryptError',\n // Identifier for a fragment parsing error event - data: { id : demuxer Id, reason : parsing error description }\n // will be renamed DEMUX_PARSING_ERROR and switched to MUX_ERROR in the next major release\n FRAG_PARSING_ERROR = 'fragParsingError',\n // Identifier for a fragment or part load skipped because of a GAP tag or attribute\n FRAG_GAP = 'fragGap',\n // Identifier for a remux alloc error event - data: { id : demuxer Id, frag : fragment object, bytes : nb of bytes on which allocation failed , reason : error text }\n REMUX_ALLOC_ERROR = 'remuxAllocError',\n // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n KEY_LOAD_ERROR = 'keyLoadError',\n // Identifier for decrypt key load timeout error - data: { frag : fragment object}\n KEY_LOAD_TIMEOUT = 'keyLoadTimeOut',\n // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { error : exception , mimeType : mimeType }\n BUFFER_ADD_CODEC_ERROR = 'bufferAddCodecError',\n // Triggered when source buffer(s) could not be created using level (manifest CODECS attribute), parsed media, or best guess codec(s) - data: { reason : error reason }\n BUFFER_INCOMPATIBLE_CODECS_ERROR = 'bufferIncompatibleCodecsError',\n // Identifier for a buffer append error - data: append error description\n BUFFER_APPEND_ERROR = 'bufferAppendError',\n // Identifier for a buffer appending error event - data: appending error description\n BUFFER_APPENDING_ERROR = 'bufferAppendingError',\n // Identifier for a buffer stalled error event\n BUFFER_STALLED_ERROR = 'bufferStalledError',\n // Identifier for a buffer full event\n BUFFER_FULL_ERROR = 'bufferFullError',\n // Identifier for a buffer seek over hole event\n BUFFER_SEEK_OVER_HOLE = 'bufferSeekOverHole',\n // Identifier for a buffer nudge on stall (playback is stuck although currentTime is in a buffered area)\n BUFFER_NUDGE_ON_STALL = 'bufferNudgeOnStall',\n // Identifier for a Interstitial Asset List load error - data: { url: faulty URL, response: { code: error code, text: error text } }\n ASSET_LIST_LOAD_ERROR = 'assetListLoadError',\n // Identifier for a Interstitial Asset List load timeout - data: { url: faulty URL, response: { code: error code, text: error text } }\n ASSET_LIST_LOAD_TIMEOUT = 'assetListLoadTimeout',\n // Identifier for a Interstitial Asset List parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }}\n ASSET_LIST_PARSING_ERROR = 'assetListParsingError',\n // Identifier for a Interstitial Asset List parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }}\n INTERSTITIAL_ASSET_ITEM_ERROR = 'interstitialAssetItemError',\n // Identifier for an internal exception happening inside hls.js while handling an event\n INTERNAL_EXCEPTION = 'internalException',\n // Identifier for an internal call to abort a loader\n INTERNAL_ABORTED = 'aborted',\n // Triggered when attachMedia fails\n ATTACH_MEDIA_ERROR = 'attachMediaError',\n // Uncategorized error\n UNKNOWN = 'unknown',\n}\n","import type {\n AssetListLoadedData,\n AssetListLoadingData,\n AudioTrackLoadedData,\n AudioTracksUpdatedData,\n AudioTrackSwitchedData,\n AudioTrackSwitchingData,\n AudioTrackUpdatedData,\n BackBufferData,\n BufferAppendedData,\n BufferAppendingData,\n BufferCodecsData,\n BufferCreatedData,\n BufferEOSData,\n BufferFlushedData,\n BufferFlushingData,\n CuesParsedData,\n ErrorData,\n FPSDropData,\n FPSDropLevelCappingData,\n FragBufferedData,\n FragChangedData,\n FragDecryptedData,\n FragLoadedData,\n FragLoadEmergencyAbortedData,\n FragLoadingData,\n FragParsedData,\n FragParsingInitSegmentData,\n FragParsingMetadataData,\n FragParsingUserdataData,\n InitPTSFoundData,\n InterstitialAssetEndedData,\n InterstitialAssetErrorData,\n InterstitialAssetPlayerCreatedData,\n InterstitialAssetStartedData,\n InterstitialEndedData,\n InterstitialsBufferedToBoundaryData,\n InterstitialsPrimaryResumed,\n InterstitialStartedData,\n InterstitialsUpdatedData,\n KeyLoadedData,\n KeyLoadingData,\n LevelLoadedData,\n LevelLoadingData,\n LevelPTSUpdatedData,\n LevelsUpdatedData,\n LevelSwitchedData,\n LevelSwitchingData,\n LevelUpdatedData,\n LiveBackBufferData,\n ManifestLoadedData,\n ManifestLoadingData,\n ManifestParsedData,\n MaxAutoLevelUpdatedData,\n MediaAttachedData,\n MediaAttachingData,\n MediaDetachedData,\n MediaDetachingData,\n MediaEndedData,\n NonNativeTextTracksData,\n SteeringManifestLoadedData,\n SubtitleFragProcessedData,\n SubtitleTrackLoadedData,\n SubtitleTracksUpdatedData,\n SubtitleTrackSwitchData,\n SubtitleTrackUpdatedData,\n TrackLoadingData,\n} from './types/events';\n\nexport enum Events {\n // Fired before MediaSource is attaching to media element\n MEDIA_ATTACHING = 'hlsMediaAttaching',\n // Fired when MediaSource has been successfully attached to media element\n MEDIA_ATTACHED = 'hlsMediaAttached',\n // Fired before detaching MediaSource from media element\n MEDIA_DETACHING = 'hlsMediaDetaching',\n // Fired when MediaSource has been detached from media element\n MEDIA_DETACHED = 'hlsMediaDetached',\n // Fired when HTMLMediaElement dispatches \"ended\" event, or stalls at end of VOD program\n MEDIA_ENDED = 'hlsMediaEnded',\n // Fired after playback stall is resolved with playing, seeked, or ended event following BUFFER_STALLED_ERROR\n STALL_RESOLVED = 'hlsStallResolved',\n // Fired when the buffer is going to be reset\n BUFFER_RESET = 'hlsBufferReset',\n // Fired when we know about the codecs that we need buffers for to push into - data: {tracks : { container, codec, levelCodec, initSegment, metadata }}\n BUFFER_CODECS = 'hlsBufferCodecs',\n // fired when sourcebuffers have been created - data: { tracks : tracks }\n BUFFER_CREATED = 'hlsBufferCreated',\n // fired when we append a segment to the buffer - data: { segment: segment object }\n BUFFER_APPENDING = 'hlsBufferAppending',\n // fired when we are done with appending a media segment to the buffer - data : { parent : segment parent that triggered BUFFER_APPENDING, pending : nb of segments waiting for appending for this segment parent}\n BUFFER_APPENDED = 'hlsBufferAppended',\n // fired when the stream is finished and we want to notify the media buffer that there will be no more data - data: { }\n BUFFER_EOS = 'hlsBufferEos',\n // fired when all buffers are full to the end of the program, after calling MediaSource.endOfStream() (unless restricted)\n BUFFERED_TO_END = 'hlsBufferedToEnd',\n // fired when the media buffer should be flushed - data { startOffset, endOffset }\n BUFFER_FLUSHING = 'hlsBufferFlushing',\n // fired when the media buffer has been flushed - data: { }\n BUFFER_FLUSHED = 'hlsBufferFlushed',\n // fired to signal that a manifest loading starts - data: { url : manifestURL}\n MANIFEST_LOADING = 'hlsManifestLoading',\n // fired after manifest has been loaded - data: { levels : [available quality levels], audioTracks : [ available audio tracks ], url : manifestURL, stats : LoaderStats }\n MANIFEST_LOADED = 'hlsManifestLoaded',\n // fired after manifest has been parsed - data: { levels : [available quality levels], firstLevel : index of first quality level appearing in Manifest}\n MANIFEST_PARSED = 'hlsManifestParsed',\n // fired when a level switch is requested - data: { level : id of new level }\n LEVEL_SWITCHING = 'hlsLevelSwitching',\n // fired when a level switch is effective - data: { level : id of new level }\n LEVEL_SWITCHED = 'hlsLevelSwitched',\n // fired when a level playlist loading starts - data: { url : level URL, level : id of level being loaded}\n LEVEL_LOADING = 'hlsLevelLoading',\n // fired when a level playlist loading finishes - data: { details : levelDetails object, level : id of loaded level, stats : LoaderStats }\n LEVEL_LOADED = 'hlsLevelLoaded',\n // fired when a level's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, level : id of updated level }\n LEVEL_UPDATED = 'hlsLevelUpdated',\n // fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }\n LEVEL_PTS_UPDATED = 'hlsLevelPtsUpdated',\n // fired to notify that levels have changed after removing a level - data: { levels : [available quality levels] }\n LEVELS_UPDATED = 'hlsLevelsUpdated',\n // fired to notify that audio track lists has been updated - data: { audioTracks : audioTracks }\n AUDIO_TRACKS_UPDATED = 'hlsAudioTracksUpdated',\n // fired when an audio track switching is requested - data: { id : audio track id }\n AUDIO_TRACK_SWITCHING = 'hlsAudioTrackSwitching',\n // fired when an audio track switch actually occurs - data: { id : audio track id }\n AUDIO_TRACK_SWITCHED = 'hlsAudioTrackSwitched',\n // fired when an audio track loading starts - data: { url : audio track URL, id : audio track id }\n AUDIO_TRACK_LOADING = 'hlsAudioTrackLoading',\n // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : LoaderStats }\n AUDIO_TRACK_LOADED = 'hlsAudioTrackLoaded',\n // fired when an audio tracks's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, id : track id }\n AUDIO_TRACK_UPDATED = 'hlsAudioTrackUpdated',\n // fired to notify that subtitle track lists has been updated - data: { subtitleTracks : subtitleTracks }\n SUBTITLE_TRACKS_UPDATED = 'hlsSubtitleTracksUpdated',\n // fired to notify that subtitle tracks were cleared as a result of stopping the media\n SUBTITLE_TRACKS_CLEARED = 'hlsSubtitleTracksCleared',\n // fired when an subtitle track switch occurs - data: { id : subtitle track id }\n SUBTITLE_TRACK_SWITCH = 'hlsSubtitleTrackSwitch',\n // fired when a subtitle track loading starts - data: { url : subtitle track URL, id : subtitle track id }\n SUBTITLE_TRACK_LOADING = 'hlsSubtitleTrackLoading',\n // fired when a subtitle track loading finishes - data: { details : levelDetails object, id : subtitle track id, stats : LoaderStats }\n SUBTITLE_TRACK_LOADED = 'hlsSubtitleTrackLoaded',\n // fired when a subtitle racks's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, id : track id }\n SUBTITLE_TRACK_UPDATED = 'hlsSubtitleTrackUpdated',\n // fired when a subtitle fragment has been processed - data: { success : boolean, frag : the processed frag }\n SUBTITLE_FRAG_PROCESSED = 'hlsSubtitleFragProcessed',\n // fired when a set of VTTCues to be managed externally has been parsed - data: { type: string, track: string, cues: [ VTTCue ] }\n CUES_PARSED = 'hlsCuesParsed',\n // fired when a text track to be managed externally is found - data: { tracks: [ { label: string, kind: string, default: boolean } ] }\n NON_NATIVE_TEXT_TRACKS_FOUND = 'hlsNonNativeTextTracksFound',\n // fired when the first timestamp is found - data: { id : demuxer id, initPTS: initPTS, timescale: timescale, frag : fragment object }\n INIT_PTS_FOUND = 'hlsInitPtsFound',\n // fired when a fragment loading starts - data: { frag : fragment object }\n FRAG_LOADING = 'hlsFragLoading',\n // fired when a fragment loading is progressing - data: { frag : fragment object, { trequest, tfirst, loaded } }\n // FRAG_LOAD_PROGRESS = 'hlsFragLoadProgress',\n // Identifier for fragment load aborting for emergency switch down - data: { frag : fragment object }\n FRAG_LOAD_EMERGENCY_ABORTED = 'hlsFragLoadEmergencyAborted',\n // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : LoaderStats }\n FRAG_LOADED = 'hlsFragLoaded',\n // fired when a fragment has finished decrypting - data: { id : demuxer id, frag: fragment object, payload : fragment payload, stats : { tstart, tdecrypt } }\n FRAG_DECRYPTED = 'hlsFragDecrypted',\n // fired when Init Segment has been extracted from fragment - data: { id : demuxer id, frag: fragment object, moov : moov MP4 box, codecs : codecs found while parsing fragment }\n FRAG_PARSING_INIT_SEGMENT = 'hlsFragParsingInitSegment',\n // fired when parsing sei text is completed - data: { id : demuxer id, frag: fragment object, samples : [ sei samples pes ] }\n FRAG_PARSING_USERDATA = 'hlsFragParsingUserdata',\n // fired when parsing id3 is completed - data: { id : demuxer id, frag: fragment object, samples : [ id3 samples pes ] }\n FRAG_PARSING_METADATA = 'hlsFragParsingMetadata',\n // fired when data have been extracted from fragment - data: { id : demuxer id, frag: fragment object, data1 : moof MP4 box or TS fragments, data2 : mdat MP4 box or null}\n // FRAG_PARSING_DATA = 'hlsFragParsingData',\n // fired when fragment parsing is completed - data: { id : demuxer id, frag: fragment object }\n FRAG_PARSED = 'hlsFragParsed',\n // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id, frag : fragment object, stats : LoaderStats }\n FRAG_BUFFERED = 'hlsFragBuffered',\n // fired when fragment matching with current media position is changing - data : { id : demuxer id, frag : fragment object }\n FRAG_CHANGED = 'hlsFragChanged',\n // Identifier for a FPS drop event - data: { currentDropped, currentDecoded, totalDroppedFrames }\n FPS_DROP = 'hlsFpsDrop',\n // triggered when FPS drop triggers auto level capping - data: { level, droppedLevel }\n FPS_DROP_LEVEL_CAPPING = 'hlsFpsDropLevelCapping',\n // triggered when maxAutoLevel changes - data { autoLevelCapping, levels, maxAutoLevel, minAutoLevel, maxHdcpLevel }\n MAX_AUTO_LEVEL_UPDATED = 'hlsMaxAutoLevelUpdated',\n // Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data }\n ERROR = 'hlsError',\n // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example - data: { }\n DESTROYING = 'hlsDestroying',\n // fired when a decrypt key loading starts - data: { frag : fragment object }\n KEY_LOADING = 'hlsKeyLoading',\n // fired when a decrypt key loading is completed - data: { frag : fragment object, keyInfo : KeyLoaderInfo }\n KEY_LOADED = 'hlsKeyLoaded',\n // deprecated; please use BACK_BUFFER_REACHED - data : { bufferEnd: number }\n LIVE_BACK_BUFFER_REACHED = 'hlsLiveBackBufferReached',\n // fired when the back buffer is reached as defined by the backBufferLength config option - data : { bufferEnd: number }\n BACK_BUFFER_REACHED = 'hlsBackBufferReached',\n // fired after steering manifest has been loaded - data: { steeringManifest: SteeringManifest object, url: steering manifest URL }\n STEERING_MANIFEST_LOADED = 'hlsSteeringManifestLoaded',\n // fired when asset list has begun loading\n ASSET_LIST_LOADING = 'hlsAssetListLoading',\n // fired when a valid asset list is loaded\n ASSET_LIST_LOADED = 'hlsAssetListLoaded',\n // fired when the list of Interstitial Events and Interstitial Schedule is updated\n INTERSTITIALS_UPDATED = 'hlsInterstitialsUpdated',\n // fired when the buffer reaches an Interstitial Schedule boundary (both Primary segments and Interstitial Assets)\n INTERSTITIALS_BUFFERED_TO_BOUNDARY = 'hlsInterstitialsBufferedToBoundary',\n // fired when a player instance for an Interstitial Asset has been created\n INTERSTITIAL_ASSET_PLAYER_CREATED = 'hlsInterstitialAssetPlayerCreated',\n // Interstitial playback started\n INTERSTITIAL_STARTED = 'hlsInterstitialStarted',\n // InterstitialAsset playback started\n INTERSTITIAL_ASSET_STARTED = 'hlsInterstitialAssetStarted',\n // InterstitialAsset playback ended\n INTERSTITIAL_ASSET_ENDED = 'hlsInterstitialAssetEnded',\n // InterstitialAsset playback errored\n INTERSTITIAL_ASSET_ERROR = 'hlsInterstitialAssetError',\n // Interstitial playback ended\n INTERSTITIAL_ENDED = 'hlsInterstitialEnded',\n // Interstitial schedule resumed primary playback\n INTERSTITIALS_PRIMARY_RESUMED = 'hlsInterstitialsPrimaryResumed',\n // Interstitial players dispatch this event when playout limit is reached\n PLAYOUT_LIMIT_REACHED = 'hlsPlayoutLimitReached',\n // Event DateRange cue \"enter\" event dispatched\n EVENT_CUE_ENTER = 'hlsEventCueEnter',\n}\n\n/**\n * Defines each Event type and payload by Event name. Used in {@link hls.js#HlsEventEmitter} to strongly type the event listener API.\n */\nexport interface HlsListeners {\n [Events.MEDIA_ATTACHING]: (\n event: Events.MEDIA_ATTACHING,\n data: MediaAttachingData,\n ) => void;\n [Events.MEDIA_ATTACHED]: (\n event: Events.MEDIA_ATTACHED,\n data: MediaAttachedData,\n ) => void;\n [Events.MEDIA_DETACHING]: (\n event: Events.MEDIA_DETACHING,\n data: MediaDetachingData,\n ) => void;\n [Events.MEDIA_DETACHED]: (\n event: Events.MEDIA_DETACHED,\n data: MediaDetachedData,\n ) => void;\n [Events.MEDIA_ENDED]: (\n event: Events.MEDIA_ENDED,\n data: MediaEndedData,\n ) => void;\n [Events.STALL_RESOLVED]: (event: Events.STALL_RESOLVED, data: {}) => void;\n [Events.BUFFER_RESET]: (event: Events.BUFFER_RESET) => void;\n [Events.BUFFER_CODECS]: (\n event: Events.BUFFER_CODECS,\n data: BufferCodecsData,\n ) => void;\n [Events.BUFFER_CREATED]: (\n event: Events.BUFFER_CREATED,\n data: BufferCreatedData,\n ) => void;\n [Events.BUFFER_APPENDING]: (\n event: Events.BUFFER_APPENDING,\n data: BufferAppendingData,\n ) => void;\n [Events.BUFFER_APPENDED]: (\n event: Events.BUFFER_APPENDED,\n data: BufferAppendedData,\n ) => void;\n [Events.BUFFER_EOS]: (event: Events.BUFFER_EOS, data: BufferEOSData) => void;\n [Events.BUFFERED_TO_END]: (event: Events.BUFFERED_TO_END) => void;\n [Events.BUFFER_FLUSHING]: (\n event: Events.BUFFER_FLUSHING,\n data: BufferFlushingData,\n ) => void;\n [Events.BUFFER_FLUSHED]: (\n event: Events.BUFFER_FLUSHED,\n data: BufferFlushedData,\n ) => void;\n [Events.MANIFEST_LOADING]: (\n event: Events.MANIFEST_LOADING,\n data: ManifestLoadingData,\n ) => void;\n [Events.MANIFEST_LOADED]: (\n event: Events.MANIFEST_LOADED,\n data: ManifestLoadedData,\n ) => void;\n [Events.MANIFEST_PARSED]: (\n event: Events.MANIFEST_PARSED,\n data: ManifestParsedData,\n ) => void;\n [Events.LEVEL_SWITCHING]: (\n event: Events.LEVEL_SWITCHING,\n data: LevelSwitchingData,\n ) => void;\n [Events.LEVEL_SWITCHED]: (\n event: Events.LEVEL_SWITCHED,\n data: LevelSwitchedData,\n ) => void;\n [Events.LEVEL_LOADING]: (\n event: Events.LEVEL_LOADING,\n data: LevelLoadingData,\n ) => void;\n [Events.LEVEL_LOADED]: (\n event: Events.LEVEL_LOADED,\n data: LevelLoadedData,\n ) => void;\n [Events.LEVEL_UPDATED]: (\n event: Events.LEVEL_UPDATED,\n data: LevelUpdatedData,\n ) => void;\n [Events.LEVEL_PTS_UPDATED]: (\n event: Events.LEVEL_PTS_UPDATED,\n data: LevelPTSUpdatedData,\n ) => void;\n [Events.LEVELS_UPDATED]: (\n event: Events.LEVELS_UPDATED,\n data: LevelsUpdatedData,\n ) => void;\n [Events.AUDIO_TRACKS_UPDATED]: (\n event: Events.AUDIO_TRACKS_UPDATED,\n data: AudioTracksUpdatedData,\n ) => void;\n [Events.AUDIO_TRACK_SWITCHING]: (\n event: Events.AUDIO_TRACK_SWITCHING,\n data: AudioTrackSwitchingData,\n ) => void;\n [Events.AUDIO_TRACK_SWITCHED]: (\n event: Events.AUDIO_TRACK_SWITCHED,\n data: AudioTrackSwitchedData,\n ) => void;\n [Events.AUDIO_TRACK_LOADING]: (\n event: Events.AUDIO_TRACK_LOADING,\n data: TrackLoadingData,\n ) => void;\n [Events.AUDIO_TRACK_LOADED]: (\n event: Events.AUDIO_TRACK_LOADED,\n data: AudioTrackLoadedData,\n ) => void;\n [Events.AUDIO_TRACK_UPDATED]: (\n event: Events.AUDIO_TRACK_UPDATED,\n data: AudioTrackUpdatedData,\n ) => void;\n [Events.SUBTITLE_TRACKS_UPDATED]: (\n event: Events.SUBTITLE_TRACKS_UPDATED,\n data: SubtitleTracksUpdatedData,\n ) => void;\n [Events.SUBTITLE_TRACKS_CLEARED]: (\n event: Events.SUBTITLE_TRACKS_CLEARED,\n ) => void;\n [Events.SUBTITLE_TRACK_SWITCH]: (\n event: Events.SUBTITLE_TRACK_SWITCH,\n data: SubtitleTrackSwitchData,\n ) => void;\n [Events.SUBTITLE_TRACK_LOADING]: (\n event: Events.SUBTITLE_TRACK_LOADING,\n data: TrackLoadingData,\n ) => void;\n [Events.SUBTITLE_TRACK_LOADED]: (\n event: Events.SUBTITLE_TRACK_LOADED,\n data: SubtitleTrackLoadedData,\n ) => void;\n [Events.SUBTITLE_TRACK_UPDATED]: (\n event: Events.SUBTITLE_TRACK_UPDATED,\n data: SubtitleTrackUpdatedData,\n ) => void;\n [Events.SUBTITLE_FRAG_PROCESSED]: (\n event: Events.SUBTITLE_FRAG_PROCESSED,\n data: SubtitleFragProcessedData,\n ) => void;\n [Events.CUES_PARSED]: (\n event: Events.CUES_PARSED,\n data: CuesParsedData,\n ) => void;\n [Events.NON_NATIVE_TEXT_TRACKS_FOUND]: (\n event: Events.NON_NATIVE_TEXT_TRACKS_FOUND,\n data: NonNativeTextTracksData,\n ) => void;\n [Events.INIT_PTS_FOUND]: (\n event: Events.INIT_PTS_FOUND,\n data: InitPTSFoundData,\n ) => void;\n [Events.FRAG_LOADING]: (\n event: Events.FRAG_LOADING,\n data: FragLoadingData,\n ) => void;\n // [Events.FRAG_LOAD_PROGRESS]: TodoEventType\n [Events.FRAG_LOAD_EMERGENCY_ABORTED]: (\n event: Events.FRAG_LOAD_EMERGENCY_ABORTED,\n data: FragLoadEmergencyAbortedData,\n ) => void;\n [Events.FRAG_LOADED]: (\n event: Events.FRAG_LOADED,\n data: FragLoadedData,\n ) => void;\n [Events.FRAG_DECRYPTED]: (\n event: Events.FRAG_DECRYPTED,\n data: FragDecryptedData,\n ) => void;\n [Events.FRAG_PARSING_INIT_SEGMENT]: (\n event: Events.FRAG_PARSING_INIT_SEGMENT,\n data: FragParsingInitSegmentData,\n ) => void;\n [Events.FRAG_PARSING_USERDATA]: (\n event: Events.FRAG_PARSING_USERDATA,\n data: FragParsingUserdataData,\n ) => void;\n [Events.FRAG_PARSING_METADATA]: (\n event: Events.FRAG_PARSING_METADATA,\n data: FragParsingMetadataData,\n ) => void;\n // [Events.FRAG_PARSING_DATA]: TodoEventType\n [Events.FRAG_PARSED]: (\n event: Events.FRAG_PARSED,\n data: FragParsedData,\n ) => void;\n [Events.FRAG_BUFFERED]: (\n event: Events.FRAG_BUFFERED,\n data: FragBufferedData,\n ) => void;\n [Events.FRAG_CHANGED]: (\n event: Events.FRAG_CHANGED,\n data: FragChangedData,\n ) => void;\n [Events.FPS_DROP]: (event: Events.FPS_DROP, data: FPSDropData) => void;\n [Events.FPS_DROP_LEVEL_CAPPING]: (\n event: Events.FPS_DROP_LEVEL_CAPPING,\n data: FPSDropLevelCappingData,\n ) => void;\n [Events.MAX_AUTO_LEVEL_UPDATED]: (\n event: Events.MAX_AUTO_LEVEL_UPDATED,\n data: MaxAutoLevelUpdatedData,\n ) => void;\n [Events.ERROR]: (event: Events.ERROR, data: ErrorData) => void;\n [Events.DESTROYING]: (event: Events.DESTROYING) => void;\n [Events.KEY_LOADING]: (\n event: Events.KEY_LOADING,\n data: KeyLoadingData,\n ) => void;\n [Events.KEY_LOADED]: (event: Events.KEY_LOADED, data: KeyLoadedData) => void;\n [Events.LIVE_BACK_BUFFER_REACHED]: (\n event: Events.LIVE_BACK_BUFFER_REACHED,\n data: LiveBackBufferData,\n ) => void;\n [Events.BACK_BUFFER_REACHED]: (\n event: Events.BACK_BUFFER_REACHED,\n data: BackBufferData,\n ) => void;\n [Events.STEERING_MANIFEST_LOADED]: (\n event: Events.STEERING_MANIFEST_LOADED,\n data: SteeringManifestLoadedData,\n ) => void;\n [Events.ASSET_LIST_LOADING]: (\n event: Events.ASSET_LIST_LOADING,\n data: AssetListLoadingData,\n ) => void;\n [Events.ASSET_LIST_LOADED]: (\n event: Events.ASSET_LIST_LOADED,\n data: AssetListLoadedData,\n ) => void;\n [Events.INTERSTITIALS_UPDATED]: (\n event: Events.INTERSTITIALS_UPDATED,\n data: InterstitialsUpdatedData,\n ) => void;\n [Events.INTERSTITIALS_BUFFERED_TO_BOUNDARY]: (\n event: Events.INTERSTITIALS_BUFFERED_TO_BOUNDARY,\n data: InterstitialsBufferedToBoundaryData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_PLAYER_CREATED]: (\n event: Events.INTERSTITIAL_ASSET_PLAYER_CREATED,\n data: InterstitialAssetPlayerCreatedData,\n ) => void;\n [Events.INTERSTITIAL_STARTED]: (\n event: Events.INTERSTITIAL_STARTED,\n data: InterstitialStartedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_STARTED]: (\n event: Events.INTERSTITIAL_ASSET_STARTED,\n data: InterstitialAssetStartedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_ENDED]: (\n event: Events.INTERSTITIAL_ASSET_ENDED,\n data: InterstitialAssetEndedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_ERROR]: (\n event: Events.INTERSTITIAL_ASSET_ERROR,\n data: InterstitialAssetErrorData,\n ) => void;\n [Events.INTERSTITIAL_ENDED]: (\n event: Events.INTERSTITIAL_ENDED,\n data: InterstitialEndedData,\n ) => void;\n [Events.INTERSTITIALS_PRIMARY_RESUMED]: (\n event: Events.INTERSTITIALS_PRIMARY_RESUMED,\n data: InterstitialsPrimaryResumed,\n ) => void;\n [Events.PLAYOUT_LIMIT_REACHED]: (\n event: Events.PLAYOUT_LIMIT_REACHED,\n data: {},\n ) => void;\n [Events.EVENT_CUE_ENTER]: (event: Events.EVENT_CUE_ENTER, data: {}) => void;\n}\nexport interface HlsEventEmitter {\n on<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n once<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n\n removeAllListeners<E extends keyof HlsListeners>(event?: E): void;\n off<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener?: HlsListeners[E],\n context?: Context,\n once?: boolean,\n ): void;\n\n listeners<E extends keyof HlsListeners>(event: E): HlsListeners[E][];\n emit<E extends keyof HlsListeners>(\n event: E,\n name: E,\n eventObject: Parameters<HlsListeners[E]>[1],\n ): boolean;\n listenerCount<E extends keyof HlsListeners>(event: E): number;\n}\n","import type { LoaderConfig } from '../config';\nimport type { HlsUrlParameters, Level } from './level';\nimport type { MediaPlaylist } from './media-playlist';\nimport type { Fragment } from '../loader/fragment';\nimport type { Part } from '../loader/fragment';\nimport type { KeyLoaderInfo } from '../loader/key-loader';\nimport type { LevelDetails } from '../loader/level-details';\n\nexport interface LoaderContext {\n // target URL\n url: string;\n // loader response type (arraybuffer or default response type for playlist)\n responseType: string;\n // headers\n headers?: Record<string, string>;\n // start byte range offset\n rangeStart?: number;\n // end byte range offset\n rangeEnd?: number;\n // true if onProgress should report partial chunk of loaded content\n progressData?: boolean;\n}\n\nexport interface FragmentLoaderContext extends LoaderContext {\n frag: Fragment;\n part: Part | null;\n resetIV?: boolean;\n}\n\nexport interface KeyLoaderContext extends LoaderContext {\n keyInfo: KeyLoaderInfo;\n frag: Fragment;\n}\n\nexport interface LoaderConfiguration {\n // LoaderConfig policy that overrides required settings\n loadPolicy: LoaderConfig;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry maxNumRetry\n */\n // Max number of load retries\n maxRetry: number;\n /**\n * @deprecated use LoaderConfig maxTimeToFirstByteMs and maxLoadTimeMs\n */\n // Timeout after which `onTimeOut` callback will be triggered\n // when loading has not finished after that delay\n timeout: number;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry retryDelayMs\n */\n // Delay between an I/O error and following connection retry (ms).\n // This to avoid spamming the server\n retryDelay: number;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry maxRetryDelayMs\n */\n // max connection retry delay (ms)\n maxRetryDelay: number;\n // When streaming progressively, this is the minimum chunk size required to emit a PROGRESS event\n highWaterMark?: number;\n}\n\nexport interface LoaderResponse {\n url: string;\n data?: string | ArrayBuffer | Object;\n // Errors can include HTTP status code and error message\n // Successful responses should include status code 200\n code?: number;\n text?: string;\n}\n\nexport interface LoaderStats {\n aborted: boolean;\n loaded: number;\n retry: number;\n total: number;\n chunkCount: number;\n bwEstimate: number;\n loading: HlsProgressivePerformanceTiming;\n parsing: HlsPerformanceTiming;\n buffering: HlsProgressivePerformanceTiming;\n}\n\nexport interface HlsPerformanceTiming {\n start: number;\n end: number;\n}\n\nexport interface HlsChunkPerformanceTiming extends HlsPerformanceTiming {\n executeStart: number;\n executeEnd: number;\n}\n\nexport interface HlsProgressivePerformanceTiming extends HlsPerformanceTiming {\n first: number;\n}\n\nexport type LoaderOnSuccess<T extends LoaderContext> = (\n response: LoaderResponse,\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnProgress<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n data: string | ArrayBuffer,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnError<T extends LoaderContext> = (\n error: {\n // error status code\n code: number;\n // error description\n text: string;\n },\n context: T,\n networkDetails: any,\n stats: LoaderStats,\n) => void;\n\nexport type LoaderOnTimeout<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnAbort<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport interface LoaderCallbacks<T extends LoaderContext> {\n onSuccess: LoaderOnSuccess<T>;\n onError: LoaderOnError<T>;\n onTimeout: LoaderOnTimeout<T>;\n onAbort?: LoaderOnAbort<T>;\n onProgress?: LoaderOnProgress<T>;\n}\n\nexport interface Loader<T extends LoaderContext> {\n destroy(): void;\n abort(): void;\n load(\n context: T,\n config: LoaderConfiguration,\n callbacks: LoaderCallbacks<T>,\n ): void;\n /**\n * `getCacheAge()` is called by hls.js to get the duration that a given object\n * has been sitting in a cache proxy when playing live. If implemented,\n * this should return a value in seconds.\n *\n * For HTTP based loaders, this should return the contents of the \"age\" header.\n *\n * @returns time object being lodaded\n */\n getCacheAge?: () => number | null;\n getResponseHeader?: (name: string) => string | null;\n context: T | null;\n stats: LoaderStats;\n}\n\nexport const enum PlaylistContextType {\n MANIFEST = 'manifest',\n LEVEL = 'level',\n AUDIO_TRACK = 'audioTrack',\n SUBTITLE_TRACK = 'subtitleTrack',\n}\n\nexport const enum PlaylistLevelType {\n MAIN = 'main',\n AUDIO = 'audio',\n SUBTITLE = 'subtitle',\n}\n\nexport interface PlaylistLoaderContext extends LoaderContext {\n type: PlaylistContextType;\n // the level index to load\n level: number | null;\n // level or track id from LevelLoadingData / TrackLoadingData\n id: number | null;\n // Media Playlist Group ID\n groupId?: string;\n // Content Steering Pathway ID (or undefined for default Pathway \".\")\n pathwayId?: string;\n // internal representation of a parsed m3u8 level playlist\n levelDetails?: LevelDetails;\n // Blocking playlist request delivery directives (or null id none were added to playlist url\n deliveryDirectives: HlsUrlParameters | null;\n // Reference to level or track object in hls.levels, hls.allAudioTracks, or hls.allSubtitleTracks (null when loading MVP)\n levelOrTrack: Level | MediaPlaylist | null;\n}\n","/*\n * compute an Exponential Weighted moving average\n * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average\n * - heavily inspired from shaka-player\n */\n\nclass EWMA {\n public readonly halfLife: number;\n private alpha_: number;\n private estimate_: number;\n private totalWeight_: number;\n\n // About half of the estimated value will be from the last |halfLife| samples by weight.\n constructor(halfLife: number, estimate: number = 0, weight: number = 0) {\n this.halfLife = halfLife;\n // Larger values of alpha expire historical data more slowly.\n this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;\n this.estimate_ = estimate;\n this.totalWeight_ = weight;\n }\n\n sample(weight: number, value: number) {\n const adjAlpha = Math.pow(this.alpha_, weight);\n this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_;\n this.totalWeight_ += weight;\n }\n\n getTotalWeight(): number {\n return this.totalWeight_;\n }\n\n getEstimate(): number {\n if (this.alpha_) {\n const zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);\n if (zeroFactor) {\n return this.estimate_ / zeroFactor;\n }\n }\n return this.estimate_;\n }\n}\n\nexport default EWMA;\n","/*\n * EWMA Bandwidth Estimator\n * - heavily inspired from shaka-player\n * Tracks bandwidth samples and estimates available bandwidth.\n * Based on the minimum of two exponentially-weighted moving averages with\n * different half-lives.\n */\n\nimport EWMA from '../utils/ewma';\n\nclass EwmaBandWidthEstimator {\n private defaultEstimate_: number;\n private minWeight_: number;\n private minDelayMs_: number;\n private slow_: EWMA;\n private fast_: EWMA;\n private defaultTTFB_: number;\n private ttfb_: EWMA;\n\n constructor(\n slow: number,\n fast: number,\n defaultEstimate: number,\n defaultTTFB: number = 100,\n ) {\n this.defaultEstimate_ = defaultEstimate;\n this.minWeight_ = 0.001;\n this.minDelayMs_ = 50;\n this.slow_ = new EWMA(slow);\n this.fast_ = new EWMA(fast);\n this.defaultTTFB_ = defaultTTFB;\n this.ttfb_ = new EWMA(slow);\n }\n\n update(slow: number, fast: number) {\n const { slow_, fast_, ttfb_ } = this;\n if (slow_.halfLife !== slow) {\n this.slow_ = new EWMA(slow, slow_.getEstimate(), slow_.getTotalWeight());\n }\n if (fast_.halfLife !== fast) {\n this.fast_ = new EWMA(fast, fast_.getEstimate(), fast_.getTotalWeight());\n }\n if (ttfb_.halfLife !== slow) {\n this.ttfb_ = new EWMA(slow, ttfb_.getEstimate(), ttfb_.getTotalWeight());\n }\n }\n\n sample(durationMs: number, numBytes: number) {\n durationMs = Math.max(durationMs, this.minDelayMs_);\n const numBits = 8 * numBytes;\n // weight is duration in seconds\n const durationS = durationMs / 1000;\n // value is bandwidth in bits/s\n const bandwidthInBps = numBits / durationS;\n this.fast_.sample(durationS, bandwidthInBps);\n this.slow_.sample(durationS, bandwidthInBps);\n }\n\n sampleTTFB(ttfb: number) {\n // weight is frequency curve applied to TTFB in seconds\n // (longer times have less weight with expected input under 1 second)\n const seconds = ttfb / 1000;\n const weight = Math.sqrt(2) * Math.exp(-Math.pow(seconds, 2) / 2);\n this.ttfb_.sample(weight, Math.max(ttfb, 5));\n }\n\n canEstimate(): boolean {\n return this.fast_.getTotalWeight() >= this.minWeight_;\n }\n\n getEstimate(): number {\n if (this.canEstimate()) {\n // console.log('slow estimate:'+ Math.round(this.slow_.getEstimate()));\n // console.log('fast estimate:'+ Math.round(this.fast_.getEstimate()));\n // Take the minimum of these two estimates. This should have the effect of\n // adapting down quickly, but up more slowly.\n return Math.min(this.fast_.getEstimate(), this.slow_.getEstimate());\n } else {\n return this.defaultEstimate_;\n }\n }\n\n getEstimateTTFB(): number {\n if (this.ttfb_.getTotalWeight() >= this.minWeight_) {\n return this.ttfb_.getEstimate();\n } else {\n return this.defaultTTFB_;\n }\n }\n\n get defaultEstimate(): number {\n return this.defaultEstimate_;\n }\n\n destroy() {}\n}\nexport default EwmaBandWidthEstimator;\n","export interface ILogFunction {\n (message?: any, ...optionalParams: any[]): void;\n}\n\nexport interface ILogger {\n trace: ILogFunction;\n debug: ILogFunction;\n log: ILogFunction;\n warn: ILogFunction;\n info: ILogFunction;\n error: ILogFunction;\n}\n\nexport class Logger implements ILogger {\n trace: ILogFunction;\n debug: ILogFunction;\n log: ILogFunction;\n warn: ILogFunction;\n info: ILogFunction;\n error: ILogFunction;\n\n constructor(label: string, logger: ILogger) {\n const lb = `[${label}]:`;\n this.trace = noop;\n this.debug = logger.debug.bind(null, lb);\n this.log = logger.log.bind(null, lb);\n this.warn = logger.warn.bind(null, lb);\n this.info = logger.info.bind(null, lb);\n this.error = logger.error.bind(null, lb);\n }\n}\n\nconst noop: ILogFunction = function () {};\n\nconst fakeLogger: ILogger = {\n trace: noop,\n debug: noop,\n log: noop,\n warn: noop,\n info: noop,\n error: noop,\n};\n\nfunction createLogger() {\n return Object.assign({}, fakeLogger);\n}\n\n// let lastCallTime;\n// function formatMsgWithTimeInfo(type, msg) {\n// const now = Date.now();\n// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';\n// lastCallTime = now;\n// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';\n// return msg;\n// }\n\nfunction consolePrintFn(type: string, id: string | undefined): ILogFunction {\n const func: ILogFunction = self.console[type];\n return func\n ? func.bind(self.console, `${id ? '[' + id + '] ' : ''}[${type}] >`)\n : noop;\n}\n\nfunction getLoggerFn(\n key: string,\n debugConfig: boolean | Partial<ILogger>,\n id?: string,\n): ILogFunction {\n return debugConfig[key]\n ? debugConfig[key].bind(debugConfig)\n : consolePrintFn(key, id);\n}\n\nconst exportedLogger: ILogger = createLogger();\n\nexport function enableLogs(\n debugConfig: boolean | ILogger,\n context: string,\n id?: string | undefined,\n): ILogger {\n // check that console is available\n const newLogger = createLogger();\n if (\n (typeof console === 'object' && debugConfig === true) ||\n typeof debugConfig === 'object'\n ) {\n const keys: (keyof ILogger)[] = [\n // Remove out from list here to hard-disable a log-level\n // 'trace',\n 'debug',\n 'log',\n 'info',\n 'warn',\n 'error',\n ];\n keys.forEach((key) => {\n newLogger[key] = getLoggerFn(key, debugConfig, id);\n });\n // Some browsers don't allow to use bind on console object anyway\n // fallback to default if needed\n try {\n newLogger.log(\n `Debug logs enabled for \"${context}\" in hls.js version ${__VERSION__}`,\n );\n } catch (e) {\n /* log fn threw an exception. All logger methods are no-ops. */\n return createLogger();\n }\n // global exported logger uses the same functions as new logger without `id`\n keys.forEach((key) => {\n exportedLogger[key] = getLoggerFn(key, debugConfig);\n });\n } else {\n // Reset global exported logger\n Object.assign(exportedLogger, newLogger);\n }\n return newLogger;\n}\n\nexport const logger: ILogger = exportedLogger;\n","// This file is inserted as a shim for modules which we do not want to include into the distro.\n// This replacement is done in the \"alias\" plugin of the rollup config.\n// Use a ES dedicated file as Rollup assigns an object in the output\n// For example: \"var KeySystemFormats = emptyEs.KeySystemFormats;\"\nmodule.exports = {};\n","import type { BaseTrackSet } from '../types/buffer';\n\nexport function getMediaSource(\n preferManagedMediaSource = true,\n): typeof MediaSource | undefined {\n if (typeof self === 'undefined') return undefined;\n const mms =\n (preferManagedMediaSource || !self.MediaSource) &&\n ((self as any).ManagedMediaSource as undefined | typeof MediaSource);\n return (\n mms ||\n self.MediaSource ||\n ((self as any).WebKitMediaSource as typeof MediaSource)\n );\n}\n\nexport function isManagedMediaSource(source: typeof MediaSource | undefined) {\n return (\n typeof self !== 'undefined' && source === (self as any).ManagedMediaSource\n );\n}\n\nexport function isCompatibleTrackChange(\n currentTracks: BaseTrackSet,\n requiredTracks: BaseTrackSet,\n): boolean {\n const trackNames = Object.keys(currentTracks);\n const requiredTrackNames = Object.keys(requiredTracks);\n const trackCount = trackNames.length;\n const requiredTrackCount = requiredTrackNames.length;\n return (\n !trackCount ||\n !requiredTrackCount ||\n (trackCount === requiredTrackCount &&\n !trackNames.some((name) => requiredTrackNames.indexOf(name) === -1))\n );\n}\n","// http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197\n// http://www.onicos.com/staff/iz/a