From 177a54128bd594b3cbed0eb051dc664fb17cdcb0 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Sun, 24 Dec 2023 23:55:30 +0530 Subject: [PATCH] add build --- dist/index.d.ts | 3406 +++++++++++++++++++++++++++++++++++++++++++++ dist/index.js | 5 + dist/index.js.map | 1 + 3 files changed, 3412 insertions(+) create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/index.js.map diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..a07b6c7 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,3406 @@ +declare interface AbrComponentAPI extends ComponentAPI { + nextAutoLevel: number; + readonly bwEstimator?: EwmaBandWidthEstimator; +} + +declare class AbrController implements AbrComponentAPI { + protected hls: Hls; + private lastLevelLoadSec; + private lastLoadedFragLevel; + private _nextAutoLevel; + private nextAutoLevelKey; + private audioTracksByGroup; + private codecTiers; + private timer; + private onCheck; + private fragCurrent; + private partCurrent; + private bitrateTestDelay; + bwEstimator: EwmaBandWidthEstimator; + constructor(hls: Hls); + resetEstimator(abrEwmaDefaultEstimate?: number): void; + private initEstimator; + protected registerListeners(): void; + protected unregisterListeners(): void; + destroy(): void; + protected onManifestLoading(event: Events.MANIFEST_LOADING, data: ManifestLoadingData): void; + private onLevelsUpdated; + protected onFragLoading(event: Events.FRAG_LOADING, data: FragLoadingData): void; + protected onLevelSwitching(event: Events.LEVEL_SWITCHING, data: LevelSwitchingData): void; + protected onError(event: Events.ERROR, data: ErrorData): void; + private getTimeToLoadFrag; + protected onLevelLoaded(event: Events.LEVEL_LOADED, data: LevelLoadedData): void; + private _abandonRulesCheck; + protected onFragLoaded(event: Events.FRAG_LOADED, { frag, part }: FragLoadedData): void; + protected onFragBuffered(event: Events.FRAG_BUFFERED, data: FragBufferedData): void; + private ignoreFragment; + clearTimer(): void; + get firstAutoLevel(): number; + get forcedAutoLevel(): number; + get nextAutoLevel(): number; + private getAutoLevelKey; + private getNextABRAutoLevel; + private getBwEstimate; + private findBestLevel; + set nextAutoLevel(nextLevel: number); +} + +declare type ABRControllerConfig = { + abrEwmaFastLive: number; + abrEwmaSlowLive: number; + abrEwmaFastVoD: number; + abrEwmaSlowVoD: number; + /** + * Default bandwidth estimate in bits/s prior to collecting fragment bandwidth samples + */ + abrEwmaDefaultEstimate: number; + abrEwmaDefaultEstimateMax: number; + abrBandWidthFactor: number; + abrBandWidthUpFactor: number; + abrMaxWithRealBitrate: boolean; + maxStarvationDelay: number; + maxLoadingDelay: number; +}; + +declare class AttrList { + [key: string]: any; + constructor(attrs: string | Record); + decimalInteger(attrName: string): number; + hexadecimalInteger(attrName: string): Uint8Array | null; + hexadecimalIntegerAsNumber(attrName: string): number; + decimalFloatingPoint(attrName: string): number; + optionalFloat(attrName: string, defaultValue: number): number; + enumeratedString(attrName: string): string | undefined; + bool(attrName: string): boolean; + decimalResolution(attrName: string): { + width: number; + height: number; + } | undefined; + static parseAttrList(input: string): Record; +} + +declare type AudioPlaylistType = 'AUDIO'; + +declare class AudioStreamController extends BaseStreamController implements NetworkComponentAPI { + private videoBuffer; + private videoTrackCC; + private waitingVideoCC; + private bufferedTrack; + private switchingTrack; + private trackId; + private waitingData; + private mainDetails; + private bufferFlushed; + private cachedTrackLoadedData; + constructor(hls: Hls, fragmentTracker: FragmentTracker, keyLoader: KeyLoader); + protected onHandlerDestroying(): void; + private _registerListeners; + private _unregisterListeners; + onInitPtsFound(event: Events.INIT_PTS_FOUND, { frag, id, initPTS, timescale }: InitPTSFoundData): void; + startLoad(startPosition: number): void; + doTick(): void; + clearWaitingFragment(): void; + protected resetLoadingState(): void; + protected onTickEnd(): void; + private doTickIdle; + protected getMaxBufferLength(mainBufferLength?: number): number; + onMediaDetaching(): void; + onAudioTracksUpdated(event: Events.AUDIO_TRACKS_UPDATED, { audioTracks }: AudioTracksUpdatedData): void; + onAudioTrackSwitching(event: Events.AUDIO_TRACK_SWITCHING, data: AudioTrackSwitchingData): void; + onManifestLoading(): void; + onLevelLoaded(event: Events.LEVEL_LOADED, data: LevelLoadedData): void; + onAudioTrackLoaded(event: Events.AUDIO_TRACK_LOADED, data: TrackLoadedData): void; + _handleFragmentLoadProgress(data: FragLoadedData): void; + protected _handleFragmentLoadComplete(fragLoadedData: FragLoadedData): void; + onBufferReset(): void; + onBufferCreated(event: Events.BUFFER_CREATED, data: BufferCreatedData): void; + onFragBuffered(event: Events.FRAG_BUFFERED, data: FragBufferedData): void; + private onError; + private onBufferFlushed; + private _handleTransmuxComplete; + private _bufferInitSegment; + protected loadFragment(frag: Fragment, track: Level, targetBufferTime: number): void; + private flushAudioIfNeeded; + private completeAudioSwitch; +} + +declare class AudioTrackController extends BasePlaylistController { + private tracks; + private groupId; + private tracksInGroup; + private trackId; + private currentTrack; + private selectDefaultTrack; + constructor(hls: Hls); + private registerListeners; + private unregisterListeners; + destroy(): void; + protected onManifestLoading(): void; + protected onManifestParsed(event: Events.MANIFEST_PARSED, data: ManifestParsedData): void; + protected onAudioTrackLoaded(event: Events.AUDIO_TRACK_LOADED, data: AudioTrackLoadedData): void; + protected onLevelLoading(event: Events.LEVEL_LOADING, data: LevelLoadingData): void; + protected onLevelSwitching(event: Events.LEVEL_SWITCHING, data: LevelSwitchingData): void; + private switchLevel; + protected onError(event: Events.ERROR, data: ErrorData): void; + get allAudioTracks(): MediaPlaylist[]; + get audioTracks(): MediaPlaylist[]; + get audioTrack(): number; + set audioTrack(newId: number); + private setAudioTrack; + private selectInitialTrack; + private findTrackId; + protected loadPlaylist(hlsUrlParameters?: HlsUrlParameters): void; +} + +declare interface AudioTrackLoadedData extends TrackLoadedData { +} + +declare interface AudioTracksUpdatedData { + audioTracks: MediaPlaylist[]; +} + +declare interface AudioTrackSwitchedData extends MediaPlaylist { +} + +declare interface AudioTrackSwitchingData extends MediaPlaylist { +} + +declare interface BackBufferData { + bufferEnd: number; +} + +declare class BasePlaylistController implements NetworkComponentAPI { + protected hls: Hls; + protected timer: number; + protected requestScheduled: number; + protected canLoad: boolean; + protected log: (msg: any) => void; + protected warn: (msg: any) => void; + constructor(hls: Hls, logPrefix: string); + destroy(): void; + protected clearTimer(): void; + startLoad(): void; + stopLoad(): void; + protected switchParams(playlistUri: string, previous: LevelDetails | undefined): HlsUrlParameters | undefined; + protected loadPlaylist(hlsUrlParameters?: HlsUrlParameters): void; + protected shouldLoadPlaylist(playlist: Level | MediaPlaylist | null | undefined): boolean; + protected shouldReloadPlaylist(playlist: Level | MediaPlaylist | null | undefined): boolean; + protected playlistLoaded(index: number, data: LevelLoadedData | AudioTrackLoadedData | TrackLoadedData, previousDetails?: LevelDetails): void; + private getDeliveryDirectives; + protected checkRetry(errorEvent: ErrorData): boolean; +} + +declare class BaseSegment { + private _byteRange; + private _url; + readonly baseurl: string; + relurl?: string; + elementaryStreams: ElementaryStreams; + constructor(baseurl: string); + setByteRange(value: string, previous?: BaseSegment): void; + get byteRange(): number[]; + get byteRangeStartOffset(): number; + get byteRangeEndOffset(): number; + get url(): string; + set url(value: string); +} + +declare class BaseStreamController extends TaskLoop implements NetworkComponentAPI { + protected hls: Hls; + protected fragPrevious: Fragment | null; + protected fragCurrent: Fragment | null; + protected fragmentTracker: FragmentTracker; + protected transmuxer: TransmuxerInterface | null; + protected _state: string; + protected playlistType: PlaylistLevelType; + protected media: HTMLMediaElement | null; + protected mediaBuffer: Bufferable | null; + protected config: HlsConfig; + protected bitrateTest: boolean; + protected lastCurrentTime: number; + protected nextLoadPosition: number; + protected startPosition: number; + protected startTimeOffset: number | null; + protected loadedmetadata: boolean; + protected retryDate: number; + protected levels: Array | null; + protected fragmentLoader: FragmentLoader; + protected keyLoader: KeyLoader; + protected levelLastLoaded: number | null; + protected startFragRequested: boolean; + protected decrypter: Decrypter; + protected initPTS: RationalTimestamp[]; + protected onvseeking: EventListener | null; + protected onvended: EventListener | null; + private readonly logPrefix; + protected log: (msg: any) => void; + protected warn: (msg: any) => void; + constructor(hls: Hls, fragmentTracker: FragmentTracker, keyLoader: KeyLoader, logPrefix: string, playlistType: PlaylistLevelType); + protected doTick(): void; + protected onTickEnd(): void; + startLoad(startPosition: number): void; + stopLoad(): void; + protected _streamEnded(bufferInfo: BufferInfo, levelDetails: LevelDetails): boolean; + protected getLevelDetails(): LevelDetails | undefined; + protected onMediaAttached(event: Events.MEDIA_ATTACHED, data: MediaAttachedData): void; + protected onMediaDetaching(): void; + protected onMediaSeeking(): void; + protected onMediaEnded(): void; + protected onManifestLoaded(event: Events.MANIFEST_LOADED, data: ManifestLoadedData): void; + protected onHandlerDestroying(): void; + protected onHandlerDestroyed(): void; + protected loadFragment(frag: Fragment, level: Level, targetBufferTime: number): void; + private _loadFragForPlayback; + protected clearTrackerIfNeeded(frag: Fragment): void; + protected flushMainBuffer(startOffset: number, endOffset: number, type?: SourceBufferName | null): void; + protected _loadInitSegment(frag: Fragment, level: Level): void; + private completeInitSegmentLoad; + protected fragContextChanged(frag: Fragment | null): boolean; + protected fragBufferedComplete(frag: Fragment, part: Part | null): void; + protected seekToStartPos(): void; + protected _handleFragmentLoadComplete(fragLoadedEndData: PartsLoadedData): void; + protected _handleFragmentLoadProgress(frag: PartsLoadedData | FragLoadedData): void; + protected _doFragLoad(frag: Fragment, level: Level, targetBufferTime?: number | null, progressCallback?: FragmentLoadProgressCallback): Promise; + private doFragPartsLoad; + private handleFragLoadError; + protected _handleTransmuxerFlush(chunkMeta: ChunkMetadata): void; + protected getCurrentContext(chunkMeta: ChunkMetadata): { + frag: Fragment; + part: Part | null; + level: Level; + } | null; + protected bufferFragmentData(data: RemuxedTrack, frag: Fragment, part: Part | null, chunkMeta: ChunkMetadata, noBacktracking?: boolean): void; + protected flushBufferGap(frag: Fragment): void; + protected getFwdBufferInfo(bufferable: Bufferable | null, type: PlaylistLevelType): BufferInfo | null; + protected getFwdBufferInfoAtPos(bufferable: Bufferable | null, pos: number, type: PlaylistLevelType): BufferInfo | null; + protected getMaxBufferLength(levelBitrate?: number): number; + protected reduceMaxBufferLength(threshold: number): boolean; + protected getAppendedFrag(position: number, playlistType?: PlaylistLevelType): Fragment | null; + protected getNextFragment(pos: number, levelDetails: LevelDetails): Fragment | null; + protected isLoopLoading(frag: Fragment, targetBufferTime: number): boolean; + protected getNextFragmentLoopLoading(frag: Fragment, levelDetails: LevelDetails, bufferInfo: BufferInfo, playlistType: PlaylistLevelType, maxBufLen: number): Fragment | null; + mapToInitFragWhenRequired(frag: Fragment | null): typeof frag; + getNextPart(partList: Part[], frag: Fragment, targetBufferTime: number): number; + private loadedEndOfParts; + protected getInitialLiveFragment(levelDetails: LevelDetails, fragments: Array): Fragment | null; + protected getFragmentAtPosition(bufferEnd: number, end: number, levelDetails: LevelDetails): Fragment | null; + protected synchronizeToLiveEdge(levelDetails: LevelDetails): void; + protected alignPlaylists(details: LevelDetails, previousDetails?: LevelDetails): number; + protected waitForCdnTuneIn(details: LevelDetails): boolean | 0; + protected setStartPosition(details: LevelDetails, sliding: number): void; + protected getLoadPosition(): number; + private handleFragLoadAborted; + protected resetFragmentLoading(frag: Fragment): void; + protected onFragmentOrKeyLoadError(filterType: PlaylistLevelType, data: ErrorData): void; + protected reduceLengthAndFlushBuffer(data: ErrorData): boolean; + protected resetFragmentErrors(filterType: PlaylistLevelType): void; + protected afterBufferFlushed(media: Bufferable, bufferType: SourceBufferName, playlistType: PlaylistLevelType): void; + protected resetLoadingState(): void; + protected resetStartWhenNotLoaded(level: number): void; + protected resetWhenMissingContext(chunkMeta: ChunkMetadata): void; + protected removeUnbufferedFrags(start?: number): void; + private updateLevelTiming; + protected resetTransmuxer(): void; + protected recoverWorkerError(data: ErrorData): void; + set state(nextState: string); + get state(): string; +} + +declare type Bufferable = { + buffered: TimeRanges; +}; + +declare interface BufferAppendedData { + type: SourceBufferName; + frag: Fragment; + part: Part | null; + chunkMeta: ChunkMetadata; + parent: PlaylistLevelType; + timeRanges: Partial>; +} + +declare interface BufferAppendingData { + type: SourceBufferName; + frag: Fragment; + part: Part | null; + chunkMeta: ChunkMetadata; + parent: PlaylistLevelType; + data: Uint8Array; +} + +declare interface BufferCodecsData { + video?: Track; + audio?: Track; +} + +declare class BufferController implements ComponentAPI { + private details; + private _objectUrl; + private operationQueue; + private listeners; + private hls; + bufferCodecEventsExpected: number; + private _bufferCodecEventsTotal; + media: HTMLMediaElement | null; + mediaSource: MediaSource | null; + private lastMpegAudioChunk; + private appendSource; + appendErrors: { + audio: number; + video: number; + audiovideo: number; + }; + tracks: TrackSet; + pendingTracks: TrackSet; + sourceBuffer: SourceBuffers; + protected log: (msg: any) => void; + protected warn: (msg: any, obj?: any) => void; + protected error: (msg: any, obj?: any) => void; + constructor(hls: Hls); + hasSourceTypes(): boolean; + destroy(): void; + protected registerListeners(): void; + protected unregisterListeners(): void; + private _initSourceBuffer; + private onManifestLoading; + protected onManifestParsed(event: Events.MANIFEST_PARSED, data: ManifestParsedData): void; + protected onMediaAttaching(event: Events.MEDIA_ATTACHING, data: MediaAttachingData): void; + private _onEndStreaming; + private _onStartStreaming; + protected onMediaDetaching(): void; + protected onBufferReset(): void; + private resetBuffer; + protected onBufferCodecs(event: Events.BUFFER_CODECS, data: BufferCodecsData): void; + protected appendChangeType(type: any, mimeType: any): void; + protected onBufferAppending(event: Events.BUFFER_APPENDING, eventData: BufferAppendingData): void; + protected onBufferFlushing(event: Events.BUFFER_FLUSHING, data: BufferFlushingData): void; + protected onFragParsed(event: Events.FRAG_PARSED, data: FragParsedData): void; + private onFragChanged; + protected onBufferEos(event: Events.BUFFER_EOS, data: BufferEOSData): void; + protected onLevelUpdated(event: Events.LEVEL_UPDATED, { details }: LevelUpdatedData): void; + flushBackBuffer(): void; + /** + * Update Media Source duration to current level duration or override to Infinity if configuration parameter + * 'liveDurationInfinity` is set to `true` + * More details: https://github.com/video-dev/hls.js/issues/355 + */ + private updateMediaElementDuration; + updateSeekableRange(levelDetails: any): void; + protected checkPendingTracks(): void; + protected createSourceBuffers(tracks: TrackSet): void; + private _onMediaSourceOpen; + private _onMediaSourceClose; + private _onMediaSourceEnded; + private _onMediaEmptied; + private get mediaSrc(); + private _onSBUpdateStart; + private _onSBUpdateEnd; + private _onSBUpdateError; + private removeExecutor; + private appendExecutor; + private blockBuffers; + private getSourceBufferTypes; + private addBufferListener; + private removeBufferListeners; +} + +declare type BufferControllerConfig = { + appendErrorMaxRetry: number; + backBufferLength: number; + liveDurationInfinity: boolean; + /** + * @deprecated use backBufferLength + */ + liveBackBufferLength: number | null; +}; + +declare interface BufferCreatedData { + tracks: TrackSet; +} + +declare interface BufferEOSData { + type?: SourceBufferName; +} + +declare interface BufferFlushedData { + type: SourceBufferName; +} + +declare interface BufferFlushingData { + startOffset: number; + endOffset: number; + endOffsetSubtitles?: number; + type: SourceBufferName | null; +} + +declare type BufferInfo = { + len: number; + start: number; + end: number; + nextStart?: number; +}; + +declare class CapLevelController implements ComponentAPI { + private hls; + private autoLevelCapping; + private firstLevel; + private media; + private restrictedLevels; + private timer; + private clientRect; + private streamController?; + constructor(hls: Hls); + setStreamController(streamController: StreamController): void; + destroy(): void; + protected registerListeners(): void; + protected unregisterListener(): void; + protected onFpsDropLevelCapping(event: Events.FPS_DROP_LEVEL_CAPPING, data: FPSDropLevelCappingData): void; + protected onMediaAttaching(event: Events.MEDIA_ATTACHING, data: MediaAttachingData): void; + protected onManifestParsed(event: Events.MANIFEST_PARSED, data: ManifestParsedData): void; + private onLevelsUpdated; + protected onBufferCodecs(event: Events.BUFFER_CODECS, data: BufferCodecsData): void; + protected onMediaDetaching(): void; + detectPlayerSize(): void; + getMaxLevel(capLevelIndex: number): number; + startCapping(): void; + stopCapping(): void; + getDimensions(): { + width: number; + height: number; + }; + get mediaWidth(): number; + get mediaHeight(): number; + get contentScaleFactor(): number; + private isLevelAllowed; + static getMaxLevelByMediaSize(levels: Array, width: number, height: number): number; +} + +declare type CapLevelControllerConfig = { + capLevelToPlayerSize: boolean; +}; + +/** + * Keep a CEA-608 screen of 32x15 styled characters + * @constructor + */ +declare class CaptionScreen { + rows: Row[]; + currRow: number; + nrRollUpRows: number | null; + lastOutputScreen: CaptionScreen | null; + logger: CaptionsLogger; + constructor(logger: CaptionsLogger); + reset(): void; + equals(other: CaptionScreen): boolean; + copy(other: CaptionScreen): void; + isEmpty(): boolean; + backSpace(): void; + clearToEndOfRow(): void; + /** + * Insert a character (without styling) in the current row. + */ + insertChar(char: number): void; + setPen(styles: Partial): void; + moveCursor(relPos: number): void; + setCursor(absPos: number): void; + setPAC(pacData: PACData): void; + /** + * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility). + */ + setBkgData(bkgData: Partial): void; + setRollUpRows(nrRows: number | null): void; + rollUp(): void; + /** + * Get all non-empty rows with as unicode text. + */ + getDisplayText(asOneRow?: boolean): string; + getTextAndFormat(): Row[]; +} + +declare class CaptionsLogger { + time: number | null; + verboseLevel: VerboseLevel; + log(severity: VerboseLevel, msg: string | (() => string)): void; +} + +declare class ChunkMetadata { + readonly level: number; + readonly sn: number; + readonly part: number; + readonly id: number; + readonly size: number; + readonly partial: boolean; + readonly transmuxing: HlsChunkPerformanceTiming; + readonly buffering: { + [key in SourceBufferName]: HlsChunkPerformanceTiming; + }; + constructor(level: number, sn: number, id: number, size?: number, part?: number, partial?: boolean); +} + +/** + * CMCD + */ +declare interface CMCD { + /** + * Encoded bitrate + * + * The encoded bitrate of the audio or video object being requested. This may not be known precisely by the player; however, + * it MAY be estimated based upon playlist/manifest declarations. If the playlist declares both peak and average bitrate values, + * the peak value should be transmitted. + * + * Integer kbps + */ + br?: number; + /** + * Object duration + * + * The playback duration in milliseconds of the object being requested. If a partial segment is being requested, then this value + * MUST indicate the playback duration of that part and not that of its parent segment. This value can be an approximation of the + * estimated duration if the explicit value is not known. + * + * Integer milliseconds + */ + d?: number; + /** + * Object type + * + * The media type of the current object being requested: + * - `m` = text file, such as a manifest or playlist + * - `a` = audio only + * - `v` = video only + * - `av` = muxed audio and video + * - `i` = init segment + * - `c` = caption or subtitle + * - `tt` = ISOBMFF timed text track + * - `k` = cryptographic key, license or certificate. + * - `o` = other + * + * If the object type being requested is unknown, then this key MUST NOT be used. + */ + ot?: CMCDObjectType; + /** + * Top bitrate + * + * The highest bitrate rendition in the manifest or playlist that the client is allowed to play, given current codec, licensing and + * sizing constraints. + * + * Integer Kbps + */ + tb?: number; + /** + * Buffer length + * + * The buffer length associated with the media object being requested. This value MUST be rounded to the nearest 100 ms. This key SHOULD only be + * sent with an object type of ‘a’, ‘v’ or ‘av’. + * + * Integer milliseconds + */ + bl?: number; + /** + * Deadline + * + * Deadline from the request time until the first sample of this Segment/Object needs to be available in order to not create a buffer underrun or + * any other playback problems. This value MUST be rounded to the nearest 100ms. For a playback rate of 1, this may be equivalent to the player’s + * remaining buffer length. + * + * Integer milliseconds + */ + dl?: number; + /** + * Measured mtp CMCD throughput + * + * The throughput between client and server, as measured by the client and MUST be rounded to the nearest 100 kbps. This value, however derived, + * SHOULD be the value that the client is using to make its next Adaptive Bitrate switching decision. If the client is connected to multiple + * servers concurrently, it must take care to report only the throughput measured against the receiving server. If the client has multiple concurrent + * connections to the server, then the intent is that this value communicates the aggregate throughput the client sees across all those connections. + * + * Integer kbps + */ + mtp?: number; + /** + * Next object request + * + * Relative path of the next object to be requested. This can be used to trigger pre-fetching by the CDN. This MUST be a path relative to the current + * request. This string MUST be URLEncoded. The client SHOULD NOT depend upon any pre-fetch action being taken - it is merely a request for such a + * pre-fetch to take place. + * + * String + */ + nor?: string; + /** + * Next range request + * + * If the next request will be a partial object request, then this string denotes the byte range to be requested. If the ‘nor’ field is not set, then the + * object is assumed to match the object currently being requested. The client SHOULD NOT depend upon any pre-fetch action being taken – it is merely a + * request for such a pre-fetch to take place. Formatting is similar to the HTTP Range header, except that the unit MUST be ‘byte’, the ‘Range:’ prefix is + * NOT required and specifying multiple ranges is NOT allowed. Valid combinations are: + * + * - `"\-"` + * - `"\-\"` + * - `"-\"` + * + * String + */ + nrr?: string; + /** + * Startup + * + * Key is included without a value if the object is needed urgently due to startup, seeking or recovery after a buffer-empty event. The media SHOULD not be + * rendering when this request is made. This key MUST not be sent if it is FALSE. + * + * Boolean + */ + su?: boolean; + /** + * Content ID + * + * A unique string identifying the current content. Maximum length is 64 characters. This value is consistent across multiple different + * sessions and devices and is defined and updated at the discretion of the service provider. + * + * String + */ + cid?: string; + /** + * Playback rate + * + * `1` if real-time, `2` if double speed, `0` if not playing. SHOULD only be sent if not equal to `1`. + * + * Decimal + */ + pr?: number; + /** + * Streaming format + * + * The streaming format that defines the current request. + * + * - `d` = MPEG DASH + * - `h` = HTTP Live Streaming (HLS) + * - `s` = Smooth Streaming + * - `o` = other + * + * If the streaming format being requested is unknown, then this key MUST NOT be used. + */ + sf?: typeof CMCDStreamingFormatHLS; + /** + * Session ID + * + * A GUID identifying the current playback session. A playback session typically ties together segments belonging to a single media asset. + * Maximum length is 64 characters. It is RECOMMENDED to conform to the UUID specification. + * + * String + */ + sid?: string; + /** + * Stream type + * - `v` = all segments are available – e.g., VOD + * - `l` = segments become available over time – e.g., LIVE + */ + st?: CMCDStreamType; + /** + * CMCD version + * + * The version of this specification used for interpreting the defined key names and values. If this key is omitted, the client and server MUST + * interpret the values as being defined by version 1. Client SHOULD omit this field if the version is 1. + * + * Integer + */ + v?: number; + /** + * Buffer starvation + * + * Key is included without a value if the buffer was starved at some point between the prior request and this object request, + * resulting in the player being in a rebuffering state and the video or audio playback being stalled. This key MUST NOT be + * sent if the buffer was not starved since the prior request. + * + * If the object type `ot` key is sent along with this key, then the `bs` key refers to the buffer associated with the particular + * object type. If no object type is communicated, then the buffer state applies to the current session. + * + * Boolean + */ + bs?: boolean; + /** + * Requested maximum throughput + * + * The requested maximum throughput that the client considers sufficient for delivery of the asset. Values MUST be rounded to the + * nearest 100kbps. For example, a client would indicate that the current segment, encoded at 2Mbps, is to be delivered at no more + * than 10Mbps, by using rtp=10000. + * + * Note: This can benefit clients by preventing buffer saturation through over-delivery and can also deliver a community benefit + * through fair-share delivery. The concept is that each client receives the throughput necessary for great performance, but no more. + * The CDN may not support the rtp feature. + * + * Integer kbps + */ + rtp?: number; +} + +/** + * Controller to deal with Common Media Client Data (CMCD) + * @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf + */ +declare class CMCDController implements ComponentAPI { + private hls; + private config; + private media?; + private sid?; + private cid?; + private useHeaders; + private initialized; + private starved; + private buffering; + private audioBuffer?; + private videoBuffer?; + constructor(hls: Hls); + private registerListeners; + private unregisterListeners; + destroy(): void; + private onMediaAttached; + private onMediaDetached; + private onBufferCreated; + private onWaiting; + private onPlaying; + /** + * Create baseline CMCD data + */ + private createData; + /** + * Apply CMCD data to a request. + */ + private apply; + /** + * Apply CMCD data to a manifest request. + */ + private applyPlaylistData; + /** + * Apply CMCD data to a segment request + */ + private applyFragmentData; + /** + * The CMCD object type. + */ + private getObjectType; + /** + * Get the highest bitrate. + */ + private getTopBandwidth; + /** + * Get the buffer length for a media type in milliseconds + */ + private getBufferLength; + /** + * Create a playlist loader + */ + private createPlaylistLoader; + /** + * Create a playlist loader + */ + private createFragmentLoader; + /** + * Generate a random v4 UUI + * + * @returns {string} + */ + static uuid(): string; + /** + * Serialize a CMCD data object according to the rules defined in the + * section 3.2 of + * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). + */ + static serialize(data: CMCD): string; + /** + * Convert a CMCD data object to request headers according to the rules + * defined in the section 2.1 and 3.2 of + * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). + */ + static toHeaders(data: CMCD): Partial; + /** + * Convert a CMCD data object to query args according to the rules + * defined in the section 2.2 and 3.2 of + * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf). + */ + static toQuery(data: CMCD): string; + /** + * Append query args to a uri. + */ + static appendQueryToUri(uri: any, query: any): any; +} + +declare type CMCDControllerConfig = { + sessionId?: string; + contentId?: string; + useHeaders?: boolean; +}; + +/** + * CMCD Headers + */ +declare interface CMCDHeaders { + 'CMCD-Object': string; + 'CMCD-Request': string; + 'CMCD-Session': string; + 'CMCD-Status': string; +} + +/** + * CMCD Object Type + */ +declare const enum CMCDObjectType { + MANIFEST = "m", + AUDIO = "a", + VIDEO = "v", + MUXED = "av", + INIT = "i", + CAPTION = "c", + TIMED_TEXT = "tt", + KEY = "k", + OTHER = "o" +} + +/** + * CMCD Streaming Format + */ +declare const CMCDStreamingFormatHLS = "h"; + +/** + * CMCD Streaming Type + */ +declare const enum CMCDStreamType { + VOD = "v", + LIVE = "l" +} + +declare interface ComponentAPI { + destroy(): void; +} + +declare class ContentSteeringController implements NetworkComponentAPI { + private readonly hls; + private log; + private loader; + private uri; + private pathwayId; + private pathwayPriority; + private timeToLoad; + private reloadTimer; + private updated; + private started; + private enabled; + private levels; + private audioTracks; + private subtitleTracks; + private penalizedPathways; + constructor(hls: Hls); + private registerListeners; + private unregisterListeners; + startLoad(): void; + stopLoad(): void; + clearTimeout(): void; + destroy(): void; + removeLevel(levelToRemove: Level): void; + private onManifestLoading; + private onManifestLoaded; + private onManifestParsed; + private onError; + filterParsedLevels(levels: Level[]): Level[]; + private getLevelsForPathway; + private updatePathwayPriority; + private clonePathways; + private loadSteeringManifest; + private scheduleRefresh; +} + +declare type ContentSteeringOptions = { + uri: string; + pathwayId: string; +}; + +declare interface CuesInterface { + newCue(track: TextTrack | null, startTime: number, endTime: number, captionScreen: CaptionScreen): VTTCue[]; +} + +declare interface CuesParsedData { + type: 'captions' | 'subtitles'; + cues: any; + track: string; +} + +declare class DateRange { + attr: AttrList; + private _startDate; + private _endDate?; + private _badValueForSameId?; + constructor(dateRangeAttr: AttrList, dateRangeWithSameId?: DateRange); + get id(): string; + get class(): string; + get startDate(): Date; + get endDate(): Date | null; + get duration(): number | null; + get plannedDuration(): number | null; + get endOnNext(): boolean; + get isValid(): boolean; +} + +declare interface DecryptData { + uri: string; + method: string; + keyFormat: string; + keyFormatVersions: number[]; + iv: Uint8Array | null; + key: Uint8Array | null; + keyId: Uint8Array | null; + pssh: Uint8Array | null; + encrypted: boolean; + isCommonEncryption: boolean; +} + +declare class Decrypter { + private logEnabled; + private removePKCS7Padding; + private subtle; + private softwareDecrypter; + private key; + private fastAesKey; + private remainderData; + private currentIV; + private currentResult; + private useSoftware; + constructor(config: HlsConfig, { removePKCS7Padding }?: { + removePKCS7Padding?: boolean | undefined; + }); + destroy(): void; + isSync(): boolean; + flush(): Uint8Array | null; + reset(): void; + decrypt(data: Uint8Array | ArrayBuffer, key: ArrayBuffer, iv: ArrayBuffer): Promise; + softwareDecrypt(data: Uint8Array, key: ArrayBuffer, iv: ArrayBuffer): ArrayBuffer | null; + webCryptoDecrypt(data: Uint8Array, key: ArrayBuffer, iv: ArrayBuffer): Promise; + private onWebCryptoError; + private getValidChunk; + private logOnce; +} + +declare type DRMSystemConfiguration = { + licenseUrl: string; + serverCertificateUrl?: string; + generateRequest?: (this: Hls, initDataType: string, initData: ArrayBuffer | null, keyContext: MediaKeySessionContext) => { + initDataType: string; + initData: ArrayBuffer | null; + } | undefined | never; +}; + +declare type DRMSystemOptions = { + audioRobustness?: string; + videoRobustness?: string; + audioEncryptionScheme?: string | null; + videoEncryptionScheme?: string | null; + persistentState?: MediaKeysRequirement; + distinctiveIdentifier?: MediaKeysRequirement; + sessionTypes?: string[]; + sessionType?: string; +}; + +declare type DRMSystemsConfiguration = Partial>; + +declare interface ElementaryStreamInfo { + startPTS: number; + endPTS: number; + startDTS: number; + endDTS: number; + partial?: boolean; +} + +declare type ElementaryStreams = Record; + +declare const enum ElementaryStreamTypes { + AUDIO = "audio", + VIDEO = "video", + AUDIOVIDEO = "audiovideo" +} + +/** + * Controller to deal with encrypted media extensions (EME) + * @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API + * + * @class + * @constructor + */ +declare class EMEController implements ComponentAPI { + static CDMCleanupPromise: Promise | void; + private readonly hls; + private readonly config; + private media; + private keyFormatPromise; + private keySystemAccessPromises; + private _requestLicenseFailureCount; + private mediaKeySessions; + private keyIdToKeySessionPromise; + private setMediaKeysQueue; + private onMediaEncrypted; + private onWaitingForKey; + private debug; + private log; + private warn; + private error; + constructor(hls: Hls); + destroy(): void; + private registerListeners; + private unregisterListeners; + private getLicenseServerUrl; + private getServerCertificateUrl; + private attemptKeySystemAccess; + private requestMediaKeySystemAccess; + private getMediaKeysPromise; + private createMediaKeySessionContext; + private renewKeySession; + private getKeyIdString; + private updateKeySession; + selectKeySystemFormat(frag: Fragment): Promise; + private getKeyFormatPromise; + loadKey(data: KeyLoadedData): Promise; + private throwIfDestroyed; + private handleError; + private getKeySystemForKeyPromise; + private getKeySystemSelectionPromise; + private _onMediaEncrypted; + private _onWaitingForKey; + private attemptSetMediaKeys; + private generateRequestWithPreferredKeySession; + private onKeyStatusChange; + private fetchServerCertificate; + private setMediaKeysServerCertificate; + private renewLicense; + private unpackPlayReadyKeyMessage; + private setupLicenseXHR; + private requestLicense; + private onMediaAttached; + private onMediaDetached; + private onManifestLoading; + private onManifestLoaded; + private removeSession; +} + +declare type EMEControllerConfig = { + licenseXhrSetup?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext, licenseChallenge: Uint8Array) => void | Uint8Array | Promise; + licenseResponseCallback?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext) => ArrayBuffer; + emeEnabled: boolean; + widevineLicenseUrl?: string; + drmSystems: DRMSystemsConfiguration; + drmSystemOptions: DRMSystemOptions; + requestMediaKeySystemAccessFunc: MediaKeyFunc | null; +}; + +declare const enum ErrorActionFlags { + None = 0, + MoveAllAlternatesMatchingHost = 1, + MoveAllAlternatesMatchingHDCP = 2, + SwitchToSDR = 4 +} + +declare class ErrorController implements NetworkComponentAPI { + private readonly hls; + private playlistError; + private penalizedRenditions; + private log; + private warn; + private error; + constructor(hls: Hls); + private registerListeners; + private unregisterListeners; + destroy(): void; + startLoad(startPosition: number): void; + stopLoad(): void; + private getVariantLevelIndex; + private onManifestLoading; + private onLevelUpdated; + private onError; + private keySystemError; + private getPlaylistRetryOrSwitchAction; + private getFragRetryOrSwitchAction; + private getLevelSwitchAction; + onErrorOut(event: Events.ERROR, data: ErrorData): void; + private sendAlternateToPenaltyBox; + private switchLevel; + private redundantFailover; + private penalizeRendition; +} + +declare interface ErrorData { + type: ErrorTypes; + details: ErrorDetails; + error: Error; + fatal: boolean; + errorAction?: IErrorAction; + buffer?: number; + bytes?: number; + chunkMeta?: ChunkMetadata; + context?: PlaylistLoaderContext; + event?: keyof HlsListeners | 'demuxerWorker'; + frag?: Fragment; + part?: Part | null; + level?: number | undefined; + levelRetry?: boolean; + loader?: Loader; + networkDetails?: any; + stats?: LoaderStats; + mimeType?: string; + reason?: string; + response?: LoaderResponse; + url?: string; + parent?: PlaylistLevelType; + sourceBufferName?: SourceBufferName; + /** + * @deprecated Use ErrorData.error + */ + err?: { + message: string; + }; +} + +declare enum ErrorDetails { + KEY_SYSTEM_NO_KEYS = "keySystemNoKeys", + KEY_SYSTEM_NO_ACCESS = "keySystemNoAccess", + KEY_SYSTEM_NO_SESSION = "keySystemNoSession", + KEY_SYSTEM_NO_CONFIGURED_LICENSE = "keySystemNoConfiguredLicense", + KEY_SYSTEM_LICENSE_REQUEST_FAILED = "keySystemLicenseRequestFailed", + KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED = "keySystemServerCertificateRequestFailed", + KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED = "keySystemServerCertificateUpdateFailed", + KEY_SYSTEM_SESSION_UPDATE_FAILED = "keySystemSessionUpdateFailed", + KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED = "keySystemStatusOutputRestricted", + KEY_SYSTEM_STATUS_INTERNAL_ERROR = "keySystemStatusInternalError", + MANIFEST_LOAD_ERROR = "manifestLoadError", + MANIFEST_LOAD_TIMEOUT = "manifestLoadTimeOut", + MANIFEST_PARSING_ERROR = "manifestParsingError", + MANIFEST_INCOMPATIBLE_CODECS_ERROR = "manifestIncompatibleCodecsError", + LEVEL_EMPTY_ERROR = "levelEmptyError", + LEVEL_LOAD_ERROR = "levelLoadError", + LEVEL_LOAD_TIMEOUT = "levelLoadTimeOut", + LEVEL_PARSING_ERROR = "levelParsingError", + LEVEL_SWITCH_ERROR = "levelSwitchError", + AUDIO_TRACK_LOAD_ERROR = "audioTrackLoadError", + AUDIO_TRACK_LOAD_TIMEOUT = "audioTrackLoadTimeOut", + SUBTITLE_LOAD_ERROR = "subtitleTrackLoadError", + SUBTITLE_TRACK_LOAD_TIMEOUT = "subtitleTrackLoadTimeOut", + FRAG_LOAD_ERROR = "fragLoadError", + FRAG_LOAD_TIMEOUT = "fragLoadTimeOut", + FRAG_DECRYPT_ERROR = "fragDecryptError", + FRAG_PARSING_ERROR = "fragParsingError", + FRAG_GAP = "fragGap", + REMUX_ALLOC_ERROR = "remuxAllocError", + KEY_LOAD_ERROR = "keyLoadError", + KEY_LOAD_TIMEOUT = "keyLoadTimeOut", + BUFFER_ADD_CODEC_ERROR = "bufferAddCodecError", + BUFFER_INCOMPATIBLE_CODECS_ERROR = "bufferIncompatibleCodecsError", + BUFFER_APPEND_ERROR = "bufferAppendError", + BUFFER_APPENDING_ERROR = "bufferAppendingError", + BUFFER_STALLED_ERROR = "bufferStalledError", + BUFFER_FULL_ERROR = "bufferFullError", + BUFFER_SEEK_OVER_HOLE = "bufferSeekOverHole", + BUFFER_NUDGE_ON_STALL = "bufferNudgeOnStall", + INTERNAL_EXCEPTION = "internalException", + INTERNAL_ABORTED = "aborted", + UNKNOWN = "unknown" +} + +declare enum ErrorTypes { + NETWORK_ERROR = "networkError", + MEDIA_ERROR = "mediaError", + KEY_SYSTEM_ERROR = "keySystemError", + MUX_ERROR = "muxError", + OTHER_ERROR = "otherError" +} + +declare enum Events { + MEDIA_ATTACHING = "hlsMediaAttaching", + MEDIA_ATTACHED = "hlsMediaAttached", + MEDIA_DETACHING = "hlsMediaDetaching", + MEDIA_DETACHED = "hlsMediaDetached", + BUFFER_RESET = "hlsBufferReset", + BUFFER_CODECS = "hlsBufferCodecs", + BUFFER_CREATED = "hlsBufferCreated", + BUFFER_APPENDING = "hlsBufferAppending", + BUFFER_APPENDED = "hlsBufferAppended", + BUFFER_EOS = "hlsBufferEos", + BUFFER_FLUSHING = "hlsBufferFlushing", + BUFFER_FLUSHED = "hlsBufferFlushed", + MANIFEST_LOADING = "hlsManifestLoading", + MANIFEST_LOADED = "hlsManifestLoaded", + MANIFEST_PARSED = "hlsManifestParsed", + LEVEL_SWITCHING = "hlsLevelSwitching", + LEVEL_SWITCHED = "hlsLevelSwitched", + LEVEL_LOADING = "hlsLevelLoading", + LEVEL_LOADED = "hlsLevelLoaded", + LEVEL_UPDATED = "hlsLevelUpdated", + LEVEL_PTS_UPDATED = "hlsLevelPtsUpdated", + LEVELS_UPDATED = "hlsLevelsUpdated", + AUDIO_TRACKS_UPDATED = "hlsAudioTracksUpdated", + AUDIO_TRACK_SWITCHING = "hlsAudioTrackSwitching", + AUDIO_TRACK_SWITCHED = "hlsAudioTrackSwitched", + AUDIO_TRACK_LOADING = "hlsAudioTrackLoading", + AUDIO_TRACK_LOADED = "hlsAudioTrackLoaded", + SUBTITLE_TRACKS_UPDATED = "hlsSubtitleTracksUpdated", + SUBTITLE_TRACKS_CLEARED = "hlsSubtitleTracksCleared", + SUBTITLE_TRACK_SWITCH = "hlsSubtitleTrackSwitch", + SUBTITLE_TRACK_LOADING = "hlsSubtitleTrackLoading", + SUBTITLE_TRACK_LOADED = "hlsSubtitleTrackLoaded", + SUBTITLE_FRAG_PROCESSED = "hlsSubtitleFragProcessed", + CUES_PARSED = "hlsCuesParsed", + NON_NATIVE_TEXT_TRACKS_FOUND = "hlsNonNativeTextTracksFound", + INIT_PTS_FOUND = "hlsInitPtsFound", + FRAG_LOADING = "hlsFragLoading", + FRAG_LOAD_EMERGENCY_ABORTED = "hlsFragLoadEmergencyAborted", + FRAG_LOADED = "hlsFragLoaded", + FRAG_DECRYPTED = "hlsFragDecrypted", + FRAG_PARSING_INIT_SEGMENT = "hlsFragParsingInitSegment", + FRAG_PARSING_USERDATA = "hlsFragParsingUserdata", + FRAG_PARSING_METADATA = "hlsFragParsingMetadata", + FRAG_PARSED = "hlsFragParsed", + FRAG_BUFFERED = "hlsFragBuffered", + FRAG_CHANGED = "hlsFragChanged", + FPS_DROP = "hlsFpsDrop", + FPS_DROP_LEVEL_CAPPING = "hlsFpsDropLevelCapping", + ERROR = "hlsError", + DESTROYING = "hlsDestroying", + KEY_LOADING = "hlsKeyLoading", + KEY_LOADED = "hlsKeyLoaded", + LIVE_BACK_BUFFER_REACHED = "hlsLiveBackBufferReached", + BACK_BUFFER_REACHED = "hlsBackBufferReached", + STEERING_MANIFEST_LOADED = "hlsSteeringManifestLoaded" +} + +declare class EwmaBandWidthEstimator { + private defaultEstimate_; + private minWeight_; + private minDelayMs_; + private slow_; + private fast_; + private defaultTTFB_; + private ttfb_; + constructor(slow: number, fast: number, defaultEstimate: number, defaultTTFB?: number); + update(slow: number, fast: number): void; + sample(durationMs: number, numBytes: number): void; + sampleTTFB(ttfb: number): void; + canEstimate(): boolean; + getEstimate(): number; + getEstimateTTFB(): number; + destroy(): void; +} + +declare type ExtendedSourceBuffer = SourceBuffer & { + ended?: boolean; + ending?: boolean; + changeType?: (type: string) => void; +}; + +declare class FPSController implements ComponentAPI { + private hls; + private isVideoPlaybackQualityAvailable; + private timer?; + private media; + private lastTime; + private lastDroppedFrames; + private lastDecodedFrames; + private streamController; + constructor(hls: Hls); + setStreamController(streamController: StreamController): void; + protected registerListeners(): void; + protected unregisterListeners(): void; + destroy(): void; + protected onMediaAttaching(event: Events.MEDIA_ATTACHING, data: MediaAttachingData): void; + checkFPS(video: HTMLVideoElement, decodedFrames: number, droppedFrames: number): void; + checkFPSInterval(): void; +} + +declare type FPSControllerConfig = { + capLevelOnFPSDrop: boolean; + fpsDroppedMonitoringPeriod: number; + fpsDroppedMonitoringThreshold: number; +}; + +declare interface FPSDropData { + currentDropped: number; + currentDecoded: number; + totalDroppedFrames: number; +} + +declare interface FPSDropLevelCappingData { + droppedLevel: number; + level: number; +} + +declare interface FragBufferedData { + stats: LoadStats; + frag: Fragment; + part: Part | null; + id: string; +} + +declare interface FragChangedData { + frag: Fragment; +} + +declare interface FragDecryptedData { + frag: Fragment; + payload: ArrayBuffer; + stats: { + tstart: number; + tdecrypt: number; + }; +} + +declare interface FragLoadedData { + frag: Fragment; + part: Part | null; + payload: ArrayBuffer; + networkDetails: unknown; +} + +declare interface FragLoadEmergencyAbortedData { + frag: Fragment; + part: Part | null; + stats: LoaderStats; +} + +declare interface FragLoadFailResult extends ErrorData { + frag: Fragment; + part?: Part; + response?: { + data: any; + code: number; + text: string; + url: string; + }; + networkDetails: any; +} + +declare interface FragLoadingData { + frag: Fragment; + part?: Part; + targetBufferTime: number | null; +} + +/** + * Object representing parsed data from an HLS Segment. Found in {@link hls.js#LevelDetails.fragments}. + */ +declare class Fragment extends BaseSegment { + private _decryptdata; + rawProgramDateTime: string | null; + programDateTime: number | null; + tagList: Array; + duration: number; + sn: number | 'initSegment'; + levelkeys?: { + [key: string]: LevelKey; + }; + readonly type: PlaylistLevelType; + loader: Loader | null; + keyLoader: Loader | null; + level: number; + cc: number; + startPTS?: number; + endPTS?: number; + startDTS: number; + endDTS: number; + start: number; + deltaPTS?: number; + maxStartPTS?: number; + minEndPTS?: number; + stats: LoadStats; + urlId: number; + data?: Uint8Array; + bitrateTest: boolean; + title: string | null; + initSegment: Fragment | null; + endList?: boolean; + gap?: boolean; + constructor(type: PlaylistLevelType, baseurl: string); + get decryptdata(): LevelKey | null; + get end(): number; + get endProgramDateTime(): number | null; + get encrypted(): boolean; + setKeyFormat(keyFormat: KeySystemFormats): void; + abortRequests(): void; + setElementaryStreamInfo(type: ElementaryStreamTypes, startPTS: number, endPTS: number, startDTS: number, endDTS: number, partial?: boolean): void; + clearElementaryStreamInfo(): void; +} + +declare class FragmentLoader { + private readonly config; + private loader; + private partLoadTimeout; + constructor(config: HlsConfig); + destroy(): void; + abort(): void; + load(frag: Fragment, onProgress?: FragmentLoadProgressCallback): Promise; + loadPart(frag: Fragment, part: Part, onProgress: FragmentLoadProgressCallback): Promise; + private updateStatsFromPart; + private resetLoader; +} + +/** + * @deprecated use fragLoadPolicy.default + */ +declare type FragmentLoaderConfig = { + fragLoadingTimeOut: number; + fragLoadingMaxRetry: number; + fragLoadingRetryDelay: number; + fragLoadingMaxRetryTimeout: number; +}; + +declare interface FragmentLoaderConstructor { + new (confg: HlsConfig): Loader; +} + +declare interface FragmentLoaderContext extends LoaderContext { + frag: Fragment; + part: Part | null; + resetIV?: boolean; +} + +declare type FragmentLoadProgressCallback = (result: FragLoadedData | PartsLoadedData) => void; + +declare const enum FragmentState { + NOT_LOADED = "NOT_LOADED", + APPENDING = "APPENDING", + PARTIAL = "PARTIAL", + OK = "OK" +} + +declare class FragmentTracker implements ComponentAPI { + private activePartLists; + private endListFragments; + private fragments; + private timeRanges; + private bufferPadding; + private hls; + private hasGaps; + constructor(hls: Hls); + private _registerListeners; + private _unregisterListeners; + destroy(): void; + /** + * Return a Fragment or Part with an appended range that matches the position and levelType + * Otherwise, return null + */ + getAppendedFrag(position: number, levelType: PlaylistLevelType): Fragment | Part | null; + /** + * Return a buffered Fragment that matches the position and levelType. + * A buffered Fragment is one whose loading, parsing and appending is done (completed or "partial" meaning aborted). + * If not found any Fragment, return null + */ + getBufferedFrag(position: number, levelType: PlaylistLevelType): Fragment | null; + /** + * Partial fragments effected by coded frame eviction will be removed + * The browser will unload parts of the buffer to free up memory for new buffer data + * Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable) + */ + detectEvictedFragments(elementaryStream: SourceBufferName, timeRange: TimeRanges, playlistType: PlaylistLevelType, appendedPart?: Part | null): void; + /** + * Checks if the fragment passed in is loaded in the buffer properly + * Partially loaded fragments will be registered as a partial fragment + */ + detectPartialFragments(data: FragBufferedData): void; + private removeParts; + fragBuffered(frag: Fragment, force?: true): void; + private getBufferedTimes; + /** + * Gets the partial fragment for a certain time + */ + getPartialFragment(time: number): Fragment | null; + isEndListAppended(type: PlaylistLevelType): boolean; + getState(fragment: Fragment): FragmentState; + private isTimeBuffered; + private onFragLoaded; + private onBufferAppended; + private onFragBuffered; + private hasFragment; + hasParts(type: PlaylistLevelType): boolean; + removeFragmentsInRange(start: number, end: number, playlistType: PlaylistLevelType, withGapOnly?: boolean, unbufferedOnly?: boolean): void; + removeFragment(fragment: Fragment): void; + removeAllFragments(): void; +} + +declare interface FragParsedData { + frag: Fragment; + part: Part | null; +} + +declare interface FragParsingInitSegmentData { +} + +declare interface FragParsingMetadataData { + id: string; + frag: Fragment; + details: LevelDetails; + samples: MetadataSample[]; +} + +declare interface FragParsingUserdataData { + id: string; + frag: Fragment; + details: LevelDetails; + samples: UserdataSample[]; +} + +declare type HdcpLevel = (typeof HdcpLevels)[number]; + +declare const HdcpLevels: readonly ["NONE", "TYPE-0", "TYPE-1", null]; + +/** + * The `Hls` class is the core of the HLS.js library used to instantiate player instances. + * @public + */ +declare class Hls implements HlsEventEmitter { + private static defaultConfig; + /** + * The runtime configuration used by the player. At instantiation this is combination of `hls.userConfig` merged over `Hls.DefaultConfig`. + */ + readonly config: HlsConfig; + /** + * The configuration object provided on player instantiation. + */ + readonly userConfig: Partial; + private coreComponents; + private networkControllers; + private started; + private _emitter; + private _autoLevelCapping; + private _maxHdcpLevel; + private abrController; + private bufferController; + private capLevelController; + private latencyController; + private levelController; + private streamController; + private audioTrackController; + private subtitleTrackController; + private emeController; + private cmcdController; + private _media; + private url; + private triggeringException?; + /** + * Get the video-dev/hls.js package version. + */ + static get version(): string; + /** + * Check if the required MediaSource Extensions are available. + */ + static isSupported(): boolean; + static get Events(): typeof Events; + static get ErrorTypes(): typeof ErrorTypes; + static get ErrorDetails(): typeof ErrorDetails; + /** + * Get the default configuration applied to new instances. + */ + static get DefaultConfig(): HlsConfig; + /** + * Replace the default configuration applied to new instances. + */ + static set DefaultConfig(defaultConfig: HlsConfig); + /** + * Creates an instance of an HLS client that can attach to exactly one `HTMLMediaElement`. + * @param userConfig - Configuration options applied over `Hls.DefaultConfig` + */ + constructor(userConfig?: Partial); + createController(ControllerClass: any, components: any): any; + on(event: E, listener: HlsListeners[E], context?: Context): void; + once(event: E, listener: HlsListeners[E], context?: Context): void; + removeAllListeners(event?: E | undefined): void; + off(event: E, listener?: HlsListeners[E] | undefined, context?: Context, once?: boolean | undefined): void; + listeners(event: E): HlsListeners[E][]; + emit(event: E, name: E, eventObject: Parameters[1]): boolean; + trigger(event: E, eventObject: Parameters[1]): boolean; + listenerCount(event: E): number; + /** + * Dispose of the instance + */ + destroy(): void; + /** + * Attaches Hls.js to a media element + */ + attachMedia(media: HTMLMediaElement): void; + /** + * Detach Hls.js from the media + */ + detachMedia(): void; + /** + * Set the source URL. Can be relative or absolute. + */ + loadSource(url: string): void; + /** + * Start loading data from the stream source. + * Depending on default config, client starts loading automatically when a source is set. + * + * @param startPosition - Set the start position to stream from. + * Defaults to -1 (None: starts from earliest point) + */ + startLoad(startPosition?: number): void; + /** + * Stop loading of any stream data. + */ + stopLoad(): void; + /** + * Resumes stream controller segment loading if previously started. + */ + resumeBuffering(): void; + /** + * Stops stream controller segment loading without changing 'started' state like stopLoad(). + * This allows for media buffering to be paused without interupting playlist loading. + */ + pauseBuffering(): void; + /** + * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1) + */ + swapAudioCodec(): void; + /** + * When the media-element fails, this allows to detach and then re-attach it + * as one call (convenience method). + * + * Automatic recovery of media-errors by this process is configurable. + */ + recoverMediaError(): void; + removeLevel(levelIndex: any, urlId?: number): void; + /** + * @returns an array of levels (variants) sorted by HDCP-LEVEL, RESOLUTION (height), FRAME-RATE, CODECS, VIDEO-RANGE, and BANDWIDTH + */ + get levels(): Level[]; + /** + * Index of quality level (variant) currently played + */ + get currentLevel(): number; + /** + * Set quality level index immediately. This will flush the current buffer to replace the quality asap. That means playback will interrupt at least shortly to re-buffer and re-sync eventually. Set to -1 for automatic level selection. + */ + set currentLevel(newLevel: number); + /** + * Index of next quality level loaded as scheduled by stream controller. + */ + get nextLevel(): number; + /** + * Set quality level index for next loaded data. + * This will switch the video quality asap, without interrupting playback. + * May abort current loading of data, and flush parts of buffer (outside currently played fragment region). + * @param newLevel - Pass -1 for automatic level selection + */ + set nextLevel(newLevel: number); + /** + * Return the quality level of the currently or last (of none is loaded currently) segment + */ + get loadLevel(): number; + /** + * Set quality level index for next loaded data in a conservative way. + * This will switch the quality without flushing, but interrupt current loading. + * Thus the moment when the quality switch will appear in effect will only be after the already existing buffer. + * @param newLevel - Pass -1 for automatic level selection + */ + set loadLevel(newLevel: number); + /** + * get next quality level loaded + */ + get nextLoadLevel(): number; + /** + * Set quality level of next loaded segment in a fully "non-destructive" way. + * Same as `loadLevel` but will wait for next switch (until current loading is done). + */ + set nextLoadLevel(level: number); + /** + * Return "first level": like a default level, if not set, + * falls back to index of first level referenced in manifest + */ + get firstLevel(): number; + /** + * Sets "first-level", see getter. + */ + set firstLevel(newLevel: number); + /** + * Return the desired start level for the first fragment that will be loaded. + * The default value of -1 indicates automatic start level selection. + * Setting hls.nextAutoLevel without setting a startLevel will result in + * the nextAutoLevel value being used for one fragment load. + */ + get startLevel(): number; + /** + * set start level (level of first fragment that will be played back) + * if not overrided by user, first level appearing in manifest will be used as start level + * if -1 : automatic start level selection, playback will start from level matching download bandwidth + * (determined from download of first segment) + */ + set startLevel(newLevel: number); + /** + * Whether level capping is enabled. + * Default value is set via `config.capLevelToPlayerSize`. + */ + get capLevelToPlayerSize(): boolean; + /** + * Enables or disables level capping. If disabled after previously enabled, `nextLevelSwitch` will be immediately called. + */ + set capLevelToPlayerSize(shouldStartCapping: boolean); + /** + * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`) + */ + get autoLevelCapping(): number; + /** + * Returns the current bandwidth estimate in bits per second, when available. Otherwise, `NaN` is returned. + */ + get bandwidthEstimate(): number; + set bandwidthEstimate(abrEwmaDefaultEstimate: number); + /** + * get time to first byte estimate + * @type {number} + */ + get ttfbEstimate(): number; + /** + * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`) + */ + set autoLevelCapping(newLevel: number); + get maxHdcpLevel(): HdcpLevel; + set maxHdcpLevel(value: HdcpLevel); + /** + * True when automatic level selection enabled + */ + get autoLevelEnabled(): boolean; + /** + * Level set manually (if any) + */ + get manualLevel(): number; + /** + * min level selectable in auto mode according to config.minAutoBitrate + */ + get minAutoLevel(): number; + /** + * max level selectable in auto mode according to autoLevelCapping + */ + get maxAutoLevel(): number; + get firstAutoLevel(): number; + /** + * next automatically selected quality level + */ + get nextAutoLevel(): number; + /** + * this setter is used to force next auto level. + * this is useful to force a switch down in auto mode: + * in case of load error on level N, hls.js can set nextAutoLevel to N-1 for example) + * forced value is valid for one fragment. upon successful frag loading at forced level, + * this value will be resetted to -1 by ABR controller. + */ + set nextAutoLevel(nextLevel: number); + /** + * get the datetime value relative to media.currentTime for the active level Program Date Time if present + */ + get playingDate(): Date | null; + get mainForwardBufferInfo(): BufferInfo | null; + /** + * Get the complete list of audio tracks across all media groups + */ + get allAudioTracks(): Array; + /** + * Get the list of selectable audio tracks + */ + get audioTracks(): Array; + /** + * index of the selected audio track (index in audio track lists) + */ + get audioTrack(): number; + /** + * selects an audio track, based on its index in audio track lists + */ + set audioTrack(audioTrackId: number); + /** + * get the complete list of subtitle tracks across all media groups + */ + get allSubtitleTracks(): Array; + /** + * get alternate subtitle tracks list from playlist + */ + get subtitleTracks(): Array; + /** + * index of the selected subtitle track (index in subtitle track lists) + */ + get subtitleTrack(): number; + get media(): HTMLMediaElement | null; + /** + * select an subtitle track, based on its index in subtitle track lists + */ + set subtitleTrack(subtitleTrackId: number); + /** + * Whether subtitle display is enabled or not + */ + get subtitleDisplay(): boolean; + /** + * Enable/disable subtitle display rendering + */ + set subtitleDisplay(value: boolean); + /** + * get mode for Low-Latency HLS loading + */ + get lowLatencyMode(): boolean; + /** + * Enable/disable Low-Latency HLS part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK. + */ + set lowLatencyMode(mode: boolean); + /** + * Position (in seconds) of live sync point (ie edge of live position minus safety delay defined by ```hls.config.liveSyncDuration```) + * @returns null prior to loading live Playlist + */ + get liveSyncPosition(): number | null; + /** + * Estimated position (in seconds) of live edge (ie edge of live playlist plus time sync playlist advanced) + * @returns 0 before first playlist is loaded + */ + get latency(): number; + /** + * maximum distance from the edge before the player seeks forward to ```hls.liveSyncPosition``` + * configured using ```liveMaxLatencyDurationCount``` (multiple of target duration) or ```liveMaxLatencyDuration``` + * @returns 0 before first playlist is loaded + */ + get maxLatency(): number; + /** + * target distance from the edge as calculated by the latency controller + */ + get targetLatency(): number | null; + /** + * the rate at which the edge of the current live playlist is advancing or 1 if there is none + */ + get drift(): number | null; + /** + * set to true when startLoad is called before MANIFEST_PARSED event + */ + get forceStartLoad(): boolean; +} + + +declare interface HlsChunkPerformanceTiming extends HlsPerformanceTiming { + executeStart: number; + executeEnd: number; +} + +declare type HlsConfig = { + debug: boolean | ILogger; + enableWorker: boolean; + workerPath: null | string; + enableSoftwareAES: boolean; + minAutoBitrate: number; + ignoreDevicePixelRatio: boolean; + preferManagedMediaSource: boolean; + loader: { + new (confg: HlsConfig): Loader; + }; + fLoader?: FragmentLoaderConstructor; + pLoader?: PlaylistLoaderConstructor; + fetchSetup?: (context: LoaderContext, initParams: any) => Request; + xhrSetup?: (xhr: XMLHttpRequest, url: string) => Promise | void; + audioStreamController?: typeof AudioStreamController; + audioTrackController?: typeof AudioTrackController; + subtitleStreamController?: typeof SubtitleStreamController; + subtitleTrackController?: typeof SubtitleTrackController; + timelineController?: typeof TimelineController; + emeController?: typeof EMEController; + cmcd?: CMCDControllerConfig; + cmcdController?: typeof CMCDController; + contentSteeringController?: typeof ContentSteeringController; + useMediaCapabilities: boolean; + abrController: typeof AbrController; + bufferController: typeof BufferController; + capLevelController: typeof CapLevelController; + errorController: typeof ErrorController; + fpsController: typeof FPSController; + progressive: boolean; + lowLatencyMode: boolean; +} & ABRControllerConfig & BufferControllerConfig & CapLevelControllerConfig & EMEControllerConfig & FPSControllerConfig & LevelControllerConfig & MP4RemuxerConfig & StreamControllerConfig & LatencyControllerConfig & MetadataControllerConfig & TimelineControllerConfig & TSDemuxerConfig & HlsLoadPolicies & FragmentLoaderConfig & PlaylistLoaderConfig; + +declare interface HlsEventEmitter { + on(event: E, listener: HlsListeners[E], context?: Context): void; + once(event: E, listener: HlsListeners[E], context?: Context): void; + removeAllListeners(event?: E): void; + off(event: E, listener?: HlsListeners[E], context?: Context, once?: boolean): void; + listeners(event: E): HlsListeners[E][]; + emit(event: E, name: E, eventObject: Parameters[1]): boolean; + listenerCount(event: E): number; +} + +/** + * Defines each Event type and payload by Event name. Used in {@link hls.js#HlsEventEmitter} to strongly type the event listener API. + */ +declare interface HlsListeners { + [Events.MEDIA_ATTACHING]: (event: Events.MEDIA_ATTACHING, data: MediaAttachingData) => void; + [Events.MEDIA_ATTACHED]: (event: Events.MEDIA_ATTACHED, data: MediaAttachedData) => void; + [Events.MEDIA_DETACHING]: (event: Events.MEDIA_DETACHING) => void; + [Events.MEDIA_DETACHED]: (event: Events.MEDIA_DETACHED) => void; + [Events.BUFFER_RESET]: (event: Events.BUFFER_RESET) => void; + [Events.BUFFER_CODECS]: (event: Events.BUFFER_CODECS, data: BufferCodecsData) => void; + [Events.BUFFER_CREATED]: (event: Events.BUFFER_CREATED, data: BufferCreatedData) => void; + [Events.BUFFER_APPENDING]: (event: Events.BUFFER_APPENDING, data: BufferAppendingData) => void; + [Events.BUFFER_APPENDED]: (event: Events.BUFFER_APPENDED, data: BufferAppendedData) => void; + [Events.BUFFER_EOS]: (event: Events.BUFFER_EOS, data: BufferEOSData) => void; + [Events.BUFFER_FLUSHING]: (event: Events.BUFFER_FLUSHING, data: BufferFlushingData) => void; + [Events.BUFFER_FLUSHED]: (event: Events.BUFFER_FLUSHED, data: BufferFlushedData) => void; + [Events.MANIFEST_LOADING]: (event: Events.MANIFEST_LOADING, data: ManifestLoadingData) => void; + [Events.MANIFEST_LOADED]: (event: Events.MANIFEST_LOADED, data: ManifestLoadedData) => void; + [Events.MANIFEST_PARSED]: (event: Events.MANIFEST_PARSED, data: ManifestParsedData) => void; + [Events.LEVEL_SWITCHING]: (event: Events.LEVEL_SWITCHING, data: LevelSwitchingData) => void; + [Events.LEVEL_SWITCHED]: (event: Events.LEVEL_SWITCHED, data: LevelSwitchedData) => void; + [Events.LEVEL_LOADING]: (event: Events.LEVEL_LOADING, data: LevelLoadingData) => void; + [Events.LEVEL_LOADED]: (event: Events.LEVEL_LOADED, data: LevelLoadedData) => void; + [Events.LEVEL_UPDATED]: (event: Events.LEVEL_UPDATED, data: LevelUpdatedData) => void; + [Events.LEVEL_PTS_UPDATED]: (event: Events.LEVEL_PTS_UPDATED, data: LevelPTSUpdatedData) => void; + [Events.LEVELS_UPDATED]: (event: Events.LEVELS_UPDATED, data: LevelsUpdatedData) => void; + [Events.AUDIO_TRACKS_UPDATED]: (event: Events.AUDIO_TRACKS_UPDATED, data: AudioTracksUpdatedData) => void; + [Events.AUDIO_TRACK_SWITCHING]: (event: Events.AUDIO_TRACK_SWITCHING, data: AudioTrackSwitchingData) => void; + [Events.AUDIO_TRACK_SWITCHED]: (event: Events.AUDIO_TRACK_SWITCHED, data: AudioTrackSwitchedData) => void; + [Events.AUDIO_TRACK_LOADING]: (event: Events.AUDIO_TRACK_LOADING, data: TrackLoadingData) => void; + [Events.AUDIO_TRACK_LOADED]: (event: Events.AUDIO_TRACK_LOADED, data: AudioTrackLoadedData) => void; + [Events.SUBTITLE_TRACKS_UPDATED]: (event: Events.SUBTITLE_TRACKS_UPDATED, data: SubtitleTracksUpdatedData) => void; + [Events.SUBTITLE_TRACKS_CLEARED]: (event: Events.SUBTITLE_TRACKS_CLEARED) => void; + [Events.SUBTITLE_TRACK_SWITCH]: (event: Events.SUBTITLE_TRACK_SWITCH, data: SubtitleTrackSwitchData) => void; + [Events.SUBTITLE_TRACK_LOADING]: (event: Events.SUBTITLE_TRACK_LOADING, data: TrackLoadingData) => void; + [Events.SUBTITLE_TRACK_LOADED]: (event: Events.SUBTITLE_TRACK_LOADED, data: SubtitleTrackLoadedData) => void; + [Events.SUBTITLE_FRAG_PROCESSED]: (event: Events.SUBTITLE_FRAG_PROCESSED, data: SubtitleFragProcessedData) => void; + [Events.CUES_PARSED]: (event: Events.CUES_PARSED, data: CuesParsedData) => void; + [Events.NON_NATIVE_TEXT_TRACKS_FOUND]: (event: Events.NON_NATIVE_TEXT_TRACKS_FOUND, data: NonNativeTextTracksData) => void; + [Events.INIT_PTS_FOUND]: (event: Events.INIT_PTS_FOUND, data: InitPTSFoundData) => void; + [Events.FRAG_LOADING]: (event: Events.FRAG_LOADING, data: FragLoadingData) => void; + [Events.FRAG_LOAD_EMERGENCY_ABORTED]: (event: Events.FRAG_LOAD_EMERGENCY_ABORTED, data: FragLoadEmergencyAbortedData) => void; + [Events.FRAG_LOADED]: (event: Events.FRAG_LOADED, data: FragLoadedData) => void; + [Events.FRAG_DECRYPTED]: (event: Events.FRAG_DECRYPTED, data: FragDecryptedData) => void; + [Events.FRAG_PARSING_INIT_SEGMENT]: (event: Events.FRAG_PARSING_INIT_SEGMENT, data: FragParsingInitSegmentData) => void; + [Events.FRAG_PARSING_USERDATA]: (event: Events.FRAG_PARSING_USERDATA, data: FragParsingUserdataData) => void; + [Events.FRAG_PARSING_METADATA]: (event: Events.FRAG_PARSING_METADATA, data: FragParsingMetadataData) => void; + [Events.FRAG_PARSED]: (event: Events.FRAG_PARSED, data: FragParsedData) => void; + [Events.FRAG_BUFFERED]: (event: Events.FRAG_BUFFERED, data: FragBufferedData) => void; + [Events.FRAG_CHANGED]: (event: Events.FRAG_CHANGED, data: FragChangedData) => void; + [Events.FPS_DROP]: (event: Events.FPS_DROP, data: FPSDropData) => void; + [Events.FPS_DROP_LEVEL_CAPPING]: (event: Events.FPS_DROP_LEVEL_CAPPING, data: FPSDropLevelCappingData) => void; + [Events.ERROR]: (event: Events.ERROR, data: ErrorData) => void; + [Events.DESTROYING]: (event: Events.DESTROYING) => void; + [Events.KEY_LOADING]: (event: Events.KEY_LOADING, data: KeyLoadingData) => void; + [Events.KEY_LOADED]: (event: Events.KEY_LOADED, data: KeyLoadedData) => void; + [Events.LIVE_BACK_BUFFER_REACHED]: (event: Events.LIVE_BACK_BUFFER_REACHED, data: LiveBackBufferData) => void; + [Events.BACK_BUFFER_REACHED]: (event: Events.BACK_BUFFER_REACHED, data: BackBufferData) => void; + [Events.STEERING_MANIFEST_LOADED]: (event: Events.STEERING_MANIFEST_LOADED, data: SteeringManifestLoadedData) => void; +} + +declare type HlsLoadPolicies = { + fragLoadPolicy: LoadPolicy; + keyLoadPolicy: LoadPolicy; + certLoadPolicy: LoadPolicy; + playlistLoadPolicy: LoadPolicy; + manifestLoadPolicy: LoadPolicy; + steeringManifestLoadPolicy: LoadPolicy; +}; + +declare interface HlsPerformanceTiming { + start: number; + end: number; +} + +declare interface HlsProgressivePerformanceTiming extends HlsPerformanceTiming { + first: number; +} + +declare const enum HlsSkip { + No = "", + Yes = "YES", + v2 = "v2" +} + +declare class HlsUrlParameters { + msn?: number; + part?: number; + skip?: HlsSkip; + constructor(msn?: number, part?: number, skip?: HlsSkip); + addDirectives(uri: string): string | never; +} + +declare type IErrorAction = { + action: NetworkErrorAction; + flags: ErrorActionFlags; + retryCount?: number; + retryConfig?: RetryConfig; + hdcpLevel?: HdcpLevel; + nextAutoLevel?: number; + resolved?: boolean; +}; + +declare interface ILogFunction { + (message?: any, ...optionalParams: any[]): void; +} + +declare interface ILogger { + trace: ILogFunction; + debug: ILogFunction; + log: ILogFunction; + warn: ILogFunction; + info: ILogFunction; + error: ILogFunction; +} + +declare interface InitPTSFoundData { + id: string; + frag: Fragment; + initPTS: number; + timescale: number; +} + +declare interface InitSegmentData { + tracks?: TrackSet; + initPTS: number | undefined; + timescale: number | undefined; +} + +declare interface KeyLoadedData { + frag: Fragment; + keyInfo: KeyLoaderInfo; +} + +declare class KeyLoader implements ComponentAPI { + private readonly config; + keyUriToKeyInfo: { + [keyuri: string]: KeyLoaderInfo; + }; + emeController: EMEController | null; + constructor(config: HlsConfig); + abort(type?: PlaylistLevelType): void; + detach(): void; + destroy(): void; + createKeyLoadError(frag: Fragment, details: ErrorDetails | undefined, error: Error, networkDetails?: any, response?: { + url: string; + data: undefined; + code: number; + text: string; + }): LoadError; + loadClear(loadingFrag: Fragment, encryptedFragments: Fragment[]): void | Promise; + load(frag: Fragment): Promise; + loadInternal(frag: Fragment, keySystemFormat?: KeySystemFormats): Promise; + loadKeyEME(keyInfo: KeyLoaderInfo, frag: Fragment): Promise; + loadKeyHTTP(keyInfo: KeyLoaderInfo, frag: Fragment): Promise; + private resetLoader; +} + +declare interface KeyLoaderContext extends LoaderContext { + keyInfo: KeyLoaderInfo; + frag: Fragment; +} + +declare interface KeyLoaderInfo { + decryptdata: LevelKey; + keyLoadPromise: Promise | null; + loader: Loader | null; + mediaKeySessionContext: MediaKeySessionContext | null; +} + +declare interface KeyLoadingData { + frag: Fragment; +} + +declare const enum KeySystemFormats { + CLEARKEY = "org.w3.clearkey", + FAIRPLAY = "com.apple.streamingkeydelivery", + PLAYREADY = "com.microsoft.playready", + WIDEVINE = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" +} + +/** + * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess + */ +declare const enum KeySystems { + CLEARKEY = "org.w3.clearkey", + FAIRPLAY = "com.apple.fps", + PLAYREADY = "com.microsoft.playready", + WIDEVINE = "com.widevine.alpha" +} + +declare type LatencyControllerConfig = { + liveSyncDurationCount: number; + liveMaxLatencyDurationCount: number; + liveSyncDuration?: number; + liveMaxLatencyDuration?: number; + maxLiveSyncPlaybackRate: number; +}; + +declare class Level { + readonly _attrs: LevelAttributes[]; + readonly audioCodec: string | undefined; + readonly bitrate: number; + readonly codecSet: string; + readonly frameRate: number; + readonly height: number; + readonly id: number; + readonly name: string | undefined; + readonly videoCodec: string | undefined; + readonly width: number; + readonly unknownCodecs: string[] | undefined; + audioGroupIds?: (string | undefined)[]; + details?: LevelDetails; + fragmentError: number; + loadError: number; + loaded?: { + bytes: number; + duration: number; + }; + realBitrate: number; + textGroupIds?: (string | undefined)[]; + url: string[]; + supportedPromise?: Promise; + supportedResult?: MediaDecodingInfo; + private _urlId; + private _avgBitrate; + constructor(data: LevelParsed); + get maxBitrate(): number; + get averageBitrate(): number; + get attrs(): LevelAttributes; + get codecs(): string; + get pathwayId(): string; + get videoRange(): VideoRange; + get score(): number; + get uri(): string; + get urlId(): number; + set urlId(value: number); + get audioGroupId(): string | undefined; + get textGroupId(): string | undefined; + addFallback(data: LevelParsed): void; +} + +declare interface LevelAttributes extends AttrList { + 'ALLOWED-CPC'?: string; + AUDIO?: string; + 'AVERAGE-BANDWIDTH'?: string; + BANDWIDTH?: string; + 'CLOSED-CAPTIONS'?: string; + CODECS?: string; + 'FRAME-RATE'?: string; + 'HDCP-LEVEL'?: 'TYPE-0' | 'TYPE-1' | 'NONE'; + 'PATHWAY-ID'?: string; + RESOLUTION?: string; + SCORE?: string; + 'STABLE-VARIANT-ID'?: string; + SUBTITLES?: string; + 'SUPPLEMENTAL-CODECS'?: string; + VIDEO?: string; + 'VIDEO-RANGE'?: VideoRange; +} + +declare type LevelControllerConfig = { + startLevel?: number; +}; + +/** + * Object representing parsed data from an HLS Media Playlist. Found in {@link hls.js#Level.details}. + */ +declare class LevelDetails { + PTSKnown: boolean; + alignedSliding: boolean; + averagetargetduration?: number; + endCC: number; + endSN: number; + fragments: Fragment[]; + fragmentHint?: Fragment; + partList: Part[] | null; + dateRanges: Record; + live: boolean; + ageHeader: number; + advancedDateTime?: number; + updated: boolean; + advanced: boolean; + availabilityDelay?: number; + misses: number; + startCC: number; + startSN: number; + startTimeOffset: number | null; + targetduration: number; + totalduration: number; + type: string | null; + url: string; + m3u8: string; + version: number | null; + canBlockReload: boolean; + canSkipUntil: number; + canSkipDateRanges: boolean; + skippedSegments: number; + recentlyRemovedDateranges?: string[]; + partHoldBack: number; + holdBack: number; + partTarget: number; + preloadHint?: AttrList; + renditionReports?: AttrList[]; + tuneInGoal: number; + deltaUpdateFailed?: boolean; + driftStartTime: number; + driftEndTime: number; + driftStart: number; + driftEnd: number; + encryptedFragments: Fragment[]; + playlistParsingError: Error | null; + variableList: VariableMap | null; + hasVariableRefs: boolean; + constructor(baseUrl: any); + reloaded(previous: LevelDetails | undefined): void; + get hasProgramDateTime(): boolean; + get levelTargetDuration(): number; + get drift(): number; + get edge(): number; + get partEnd(): number; + get fragmentEnd(): number; + get age(): number; + get lastPartIndex(): number; + get lastPartSn(): number; +} + +declare class LevelKey implements DecryptData { + readonly uri: string; + readonly method: string; + readonly keyFormat: string; + readonly keyFormatVersions: number[]; + readonly encrypted: boolean; + readonly isCommonEncryption: boolean; + iv: Uint8Array | null; + key: Uint8Array | null; + keyId: Uint8Array | null; + pssh: Uint8Array | null; + static clearKeyUriToKeyIdMap(): void; + constructor(method: string, uri: string, format: string, formatversions?: number[], iv?: Uint8Array | null); + isSupported(): boolean; + getDecryptData(sn: number | 'initSegment'): LevelKey | null; +} + +declare interface LevelLoadedData { + details: LevelDetails; + id: number; + level: number; + networkDetails: any; + stats: LoaderStats; + deliveryDirectives: HlsUrlParameters | null; +} + +declare interface LevelLoadingData { + id: number; + level: number; + url: string; + deliveryDirectives: HlsUrlParameters | null; +} + +declare interface LevelParsed { + attrs: LevelAttributes; + audioCodec?: string; + bitrate: number; + details?: LevelDetails; + height?: number; + id?: number; + level?: number; + name: string; + textCodec?: string; + unknownCodecs?: string[]; + url: string; + videoCodec?: string; + width?: number; +} + +declare interface LevelPTSUpdatedData { + details: LevelDetails; + level: Level; + drift: number; + type: string; + frag: Fragment; + start: number; + end: number; +} + +declare interface LevelsUpdatedData { + levels: Array; +} + +declare interface LevelSwitchedData { + level: number; +} + +declare interface LevelSwitchingData extends Omit { + level: number; +} + +declare interface LevelUpdatedData { + details: LevelDetails; + level: number; +} + +/** + * @deprecated Use BackBufferData + */ +declare interface LiveBackBufferData extends BackBufferData { +} + +declare interface Loader { + destroy(): void; + abort(): void; + load(context: T, config: LoaderConfiguration, callbacks: LoaderCallbacks): void; + /** + * `getCacheAge()` is called by hls.js to get the duration that a given object + * has been sitting in a cache proxy when playing live. If implemented, + * this should return a value in seconds. + * + * For HTTP based loaders, this should return the contents of the "age" header. + * + * @returns time object being lodaded + */ + getCacheAge?: () => number | null; + getResponseHeader?: (name: string) => string | null; + context: T | null; + stats: LoaderStats; +} + +declare interface LoaderCallbacks { + onSuccess: LoaderOnSuccess; + onError: LoaderOnError; + onTimeout: LoaderOnTimeout; + onAbort?: LoaderOnAbort; + onProgress?: LoaderOnProgress; +} + +declare type LoaderConfig = { + maxTimeToFirstByteMs: number; + maxLoadTimeMs: number; + timeoutRetry: RetryConfig | null; + errorRetry: RetryConfig | null; +}; + +declare interface LoaderConfiguration { + loadPolicy: LoaderConfig; + /** + * @deprecated use LoaderConfig timeoutRetry and errorRetry maxNumRetry + */ + maxRetry: number; + /** + * @deprecated use LoaderConfig maxTimeToFirstByteMs and maxLoadTimeMs + */ + timeout: number; + /** + * @deprecated use LoaderConfig timeoutRetry and errorRetry retryDelayMs + */ + retryDelay: number; + /** + * @deprecated use LoaderConfig timeoutRetry and errorRetry maxRetryDelayMs + */ + maxRetryDelay: number; + highWaterMark?: number; +} + +declare interface LoaderContext { + url: string; + responseType: string; + headers?: Record; + rangeStart?: number; + rangeEnd?: number; + progressData?: boolean; +} + +declare type LoaderOnAbort = (stats: LoaderStats, context: T, networkDetails: any) => void; + +declare type LoaderOnError = (error: { + code: number; + text: string; +}, context: T, networkDetails: any, stats: LoaderStats) => void; + +declare type LoaderOnProgress = (stats: LoaderStats, context: T, data: string | ArrayBuffer, networkDetails: any) => void; + +declare type LoaderOnSuccess = (response: LoaderResponse, stats: LoaderStats, context: T, networkDetails: any) => void; + +declare type LoaderOnTimeout = (stats: LoaderStats, context: T, networkDetails: any) => void; + +declare interface LoaderResponse { + url: string; + data?: string | ArrayBuffer | Object; + code?: number; + text?: string; +} + +declare class LoadError extends Error { + readonly data: FragLoadFailResult; + constructor(data: FragLoadFailResult); +} + +declare interface LoaderStats { + aborted: boolean; + loaded: number; + retry: number; + total: number; + chunkCount: number; + bwEstimate: number; + loading: HlsProgressivePerformanceTiming; + parsing: HlsPerformanceTiming; + buffering: HlsProgressivePerformanceTiming; +} + +declare type LoadPolicy = { + default: LoaderConfig; +}; + +declare class LoadStats implements LoaderStats { + aborted: boolean; + loaded: number; + retry: number; + total: number; + chunkCount: number; + bwEstimate: number; + loading: HlsProgressivePerformanceTiming; + parsing: HlsPerformanceTiming; + buffering: HlsProgressivePerformanceTiming; +} + +declare type MainPlaylistType = AudioPlaylistType | 'VIDEO'; + +declare interface ManifestLoadedData { + audioTracks: MediaPlaylist[]; + captions?: MediaPlaylist[]; + contentSteering: ContentSteeringOptions | null; + levels: LevelParsed[]; + networkDetails: any; + sessionData: Record | null; + sessionKeys: LevelKey[] | null; + startTimeOffset: number | null; + stats: LoaderStats; + subtitles?: MediaPlaylist[]; + url: string; + variableList: VariableMap | null; +} + +declare interface ManifestLoadingData { + url: string; +} + +declare interface ManifestParsedData { + levels: Level[]; + audioTracks: MediaPlaylist[]; + subtitleTracks: MediaPlaylist[]; + sessionData: Record | null; + sessionKeys: LevelKey[] | null; + firstLevel: number; + stats: LoaderStats; + audio: boolean; + video: boolean; + altAudio: boolean; +} + +declare interface MediaAttachedData { + media: HTMLMediaElement; + mediaSource?: MediaSource; +} + +declare interface MediaAttachingData { + media: HTMLMediaElement; +} + +declare interface MediaAttributes extends AttrList { + 'ASSOC-LANGUAGE'?: string; + AUTOSELECT?: 'YES' | 'NO'; + CHANNELS?: string; + CHARACTERISTICS?: string; + DEFAULT?: 'YES' | 'NO'; + FORCED?: 'YES' | 'NO'; + 'GROUP-ID': string; + 'INSTREAM-ID'?: string; + LANGUAGE?: string; + NAME: string; + 'PATHWAY-ID'?: string; + 'STABLE-RENDITION-ID'?: string; + TYPE?: 'AUDIO' | 'VIDEO' | 'SUBTITLES' | 'CLOSED-CAPTIONS'; + URI?: string; +} + +declare type MediaDecodingInfo = { + supported: boolean; + configurations: readonly MediaDecodingConfiguration[]; + decodingInfoResults: readonly MediaCapabilitiesDecodingInfo[]; + error?: Error; +}; + +declare type MediaKeyFunc = (keySystem: KeySystems, supportedConfigurations: MediaKeySystemConfiguration[]) => Promise; + +declare interface MediaKeySessionContext { + keySystem: KeySystems; + mediaKeys: MediaKeys; + decryptdata: LevelKey; + mediaKeysSession: MediaKeySession; + keyStatus: MediaKeyStatus; + licenseXhr?: XMLHttpRequest; +} + +declare interface MediaPlaylist extends Omit { + attrs: MediaAttributes; + autoselect: boolean; + default: boolean; + forced: boolean; + groupId: string; + id: number; + instreamId?: string; + lang?: string; + name: string; + type: MediaPlaylistType | 'main'; +} + +declare type MediaPlaylistType = MainPlaylistType | SubtitlePlaylistType; + +declare type MetadataControllerConfig = { + enableDateRangeMetadataCues: boolean; + enableEmsgMetadataCues: boolean; + enableID3MetadataCues: boolean; +}; + +declare interface MetadataSample { + pts: number; + dts: number; + duration: number; + len?: number; + data: Uint8Array; + type: MetadataSchema; +} + +declare const enum MetadataSchema { + audioId3 = "org.id3", + dateRange = "com.apple.quicktime.HLS", + emsg = "https://aomedia.org/emsg/ID3" +} + +declare type MP4RemuxerConfig = { + stretchShortVideoTrack: boolean; + maxAudioFramesDrift: number; +}; + +declare interface NetworkComponentAPI extends ComponentAPI { + startLoad(startPosition: number): void; + stopLoad(): void; +} + +declare const enum NetworkErrorAction { + DoNothing = 0, + SendEndCallback = 1, + SendAlternateToPenaltyBox = 2, + RemoveAlternatePermanently = 3, + InsertDiscontinuity = 4, + RetryRequest = 5 +} + +declare interface NonNativeTextTrack { + _id?: string; + label: any; + kind: string; + default: boolean; + closedCaptions?: MediaPlaylist; + subtitleTrack?: MediaPlaylist; +} + +declare interface NonNativeTextTracksData { + tracks: Array; +} + +declare interface PACData { + row: number; + indent: number | null; + color: string | null; + underline: boolean; + italics: boolean; +} + +/** + * Object representing parsed data from an HLS Partial Segment. Found in {@link hls.js#LevelDetails.partList}. + */ +declare class Part extends BaseSegment { + readonly fragOffset: number; + readonly duration: number; + readonly gap: boolean; + readonly independent: boolean; + readonly relurl: string; + readonly fragment: Fragment; + readonly index: number; + stats: LoadStats; + constructor(partAttrs: AttrList, frag: Fragment, baseurl: string, index: number, previous?: Part); + get start(): number; + get end(): number; + get loaded(): boolean; +} + +declare interface PartsLoadedData { + frag: Fragment; + part: Part | null; + partsLoaded?: FragLoadedData[]; +} + +declare type PathwayClone = { + 'BASE-ID': string; + ID: string; + 'URI-REPLACEMENT': UriReplacement; +}; + +declare class PenState { + foreground: string; + underline: boolean; + italics: boolean; + background: string; + flash: boolean; + reset(): void; + setStyles(styles: Partial): void; + isDefault(): boolean; + equals(other: PenState): boolean; + copy(newPenState: PenState): void; + toString(): string; +} + +declare type PenStyles = { + foreground: string | null; + underline: boolean; + italics: boolean; + background: string; + flash: boolean; +}; + +declare const enum PlaylistContextType { + MANIFEST = "manifest", + LEVEL = "level", + AUDIO_TRACK = "audioTrack", + SUBTITLE_TRACK = "subtitleTrack" +} + +declare const enum PlaylistLevelType { + MAIN = "main", + AUDIO = "audio", + SUBTITLE = "subtitle" +} + +/** + * @deprecated use manifestLoadPolicy.default and playlistLoadPolicy.default + */ +declare type PlaylistLoaderConfig = { + manifestLoadingTimeOut: number; + manifestLoadingMaxRetry: number; + manifestLoadingRetryDelay: number; + manifestLoadingMaxRetryTimeout: number; + levelLoadingTimeOut: number; + levelLoadingMaxRetry: number; + levelLoadingRetryDelay: number; + levelLoadingMaxRetryTimeout: number; +}; + +declare interface PlaylistLoaderConstructor { + new (confg: HlsConfig): Loader; +} + +declare interface PlaylistLoaderContext extends LoaderContext { + type: PlaylistContextType; + level: number | null; + id: number | null; + groupId?: string; + levelDetails?: LevelDetails; + deliveryDirectives: HlsUrlParameters | null; +} + +declare type RationalTimestamp = { + baseTime: number; + timescale: number; +}; + +declare interface RemuxedMetadata { + samples: MetadataSample[]; +} + +declare interface RemuxedTrack { + data1: Uint8Array; + data2?: Uint8Array; + startPTS: number; + endPTS: number; + startDTS: number; + endDTS: number; + type: SourceBufferName; + hasAudio: boolean; + hasVideo: boolean; + independent?: boolean; + firstKeyFrame?: number; + firstKeyFramePTS?: number; + nb: number; + transferredData1?: ArrayBuffer; + transferredData2?: ArrayBuffer; + dropped?: number; +} + +declare interface RemuxedUserdata { + samples: UserdataSample[]; +} + +declare interface RemuxerResult { + audio?: RemuxedTrack; + video?: RemuxedTrack; + text?: RemuxedUserdata; + id3?: RemuxedMetadata; + initSegment?: InitSegmentData; + independent?: boolean; +} + +declare type RetryConfig = { + maxNumRetry: number; + retryDelayMs: number; + maxRetryDelayMs: number; + backoff?: 'exponential' | 'linear'; +}; + +/** + * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar. + * @constructor + */ +declare class Row { + chars: StyledUnicodeChar[]; + pos: number; + currPenState: PenState; + cueStartTime: number | null; + private logger; + constructor(logger: CaptionsLogger); + equals(other: Row): boolean; + copy(other: Row): void; + isEmpty(): boolean; + /** + * Set the cursor to a valid column. + */ + setCursor(absPos: number): void; + /** + * Move the cursor relative to current position. + */ + moveCursor(relPos: number): void; + /** + * Backspace, move one step back and clear character. + */ + backSpace(): void; + insertChar(byte: number): void; + clearFromPos(startPos: number): void; + clear(): void; + clearToEndOfRow(): void; + getTextString(): string; + setPenStyles(styles: Partial): void; +} + +declare type SourceBufferName = 'video' | 'audio' | 'audiovideo'; + +declare type SourceBuffers = Partial>; + +declare type SteeringManifest = { + VERSION: 1; + TTL: number; + 'RELOAD-URI'?: string; + 'PATHWAY-PRIORITY': string[]; + 'PATHWAY-CLONES'?: PathwayClone[]; +}; + +declare interface SteeringManifestLoadedData { + steeringManifest: SteeringManifest; + url: string; +} + +declare class StreamController extends BaseStreamController implements NetworkComponentAPI { + private audioCodecSwap; + private gapController; + private level; + private _forceStartLoad; + private altAudio; + private audioOnly; + private fragPlaying; + private onvplaying; + private onvseeked; + private fragLastKbps; + private couldBacktrack; + private backtrackFragment; + private audioCodecSwitch; + private videoBuffer; + constructor(hls: Hls, fragmentTracker: FragmentTracker, keyLoader: KeyLoader); + private _registerListeners; + protected _unregisterListeners(): void; + protected onHandlerDestroying(): void; + startLoad(startPosition: number): void; + stopLoad(): void; + protected doTick(): void; + protected onTickEnd(): void; + private doTickIdle; + protected loadFragment(frag: Fragment, level: Level, targetBufferTime: number): void; + private getBufferedFrag; + private followingBufferedFrag; + immediateLevelSwitch(): void; + /** + * try to switch ASAP without breaking video playback: + * in order to ensure smooth but quick level switching, + * we need to find the next flushable buffer range + * we should take into account new segment fetch time + */ + nextLevelSwitch(): void; + private abortCurrentFrag; + protected flushMainBuffer(startOffset: number, endOffset: number): void; + protected onMediaAttached(event: Events.MEDIA_ATTACHED, data: MediaAttachedData): void; + protected onMediaDetaching(): void; + private onMediaPlaying; + private onMediaSeeked; + private onManifestLoading; + private onManifestParsed; + private onLevelLoading; + private onLevelLoaded; + protected _handleFragmentLoadProgress(data: FragLoadedData): void; + private onAudioTrackSwitching; + private onAudioTrackSwitched; + private onBufferCreated; + private onFragBuffered; + private onError; + private checkBuffer; + private onFragLoadEmergencyAborted; + private onBufferFlushed; + private onLevelsUpdated; + swapAudioCodec(): void; + /** + * Seeks to the set startPosition if not equal to the mediaElement's current time. + */ + protected seekToStartPos(): void; + private _getAudioCodec; + private _loadBitrateTestFrag; + private _handleTransmuxComplete; + private _bufferInitSegment; + getMainFwdBufferInfo(): BufferInfo | null; + private backtrack; + private checkFragmentChanged; + get nextLevel(): number; + get currentFrag(): Fragment | null; + get currentProgramDateTime(): Date | null; + get currentLevel(): number; + get nextBufferedFrag(): Fragment | null; + get forceStartLoad(): boolean; +} + +declare type StreamControllerConfig = { + autoStartLoad: boolean; + startPosition: number; + defaultAudioCodec?: string; + initialLiveManifestSize: number; + maxBufferLength: number; + maxBufferSize: number; + maxBufferHole: number; + highBufferWatchdogPeriod: number; + nudgeOffset: number; + nudgeMaxRetry: number; + maxFragLookUpTolerance: number; + maxMaxBufferLength: number; + startFragPrefetch: boolean; + testBandwidth: boolean; +}; + +/** + * Unicode character with styling and background. + * @constructor + */ +declare class StyledUnicodeChar { + uchar: string; + penState: PenState; + reset(): void; + setChar(uchar: string, newPenState: PenState): void; + setPenState(newPenState: PenState): void; + equals(other: StyledUnicodeChar): boolean; + copy(newChar: StyledUnicodeChar): void; + isEmpty(): boolean; +} + +declare interface SubtitleFragProcessed { + success: boolean; + frag: Fragment; +} + +declare interface SubtitleFragProcessedData { + success: boolean; + frag: Fragment; + error?: Error; +} + +declare type SubtitlePlaylistType = 'SUBTITLES' | 'CLOSED-CAPTIONS'; + +declare class SubtitleStreamController extends BaseStreamController implements NetworkComponentAPI { + protected levels: Array; + private currentTrackId; + private tracksBuffered; + private mainDetails; + constructor(hls: Hls, fragmentTracker: FragmentTracker, keyLoader: KeyLoader); + protected onHandlerDestroying(): void; + private _registerListeners; + private _unregisterListeners; + startLoad(startPosition: number): void; + onManifestLoading(): void; + onMediaDetaching(): void; + onLevelLoaded(event: Events.LEVEL_LOADED, data: LevelLoadedData): void; + onSubtitleFragProcessed(event: Events.SUBTITLE_FRAG_PROCESSED, data: SubtitleFragProcessed): void; + onBufferFlushing(event: Events.BUFFER_FLUSHING, data: BufferFlushingData): void; + onFragBuffered(event: Events.FRAG_BUFFERED, data: FragBufferedData): void; + onError(event: Events.ERROR, data: ErrorData): void; + onSubtitleTracksUpdated(event: Events.SUBTITLE_TRACKS_UPDATED, { subtitleTracks }: SubtitleTracksUpdatedData): void; + onSubtitleTrackSwitch(event: Events.SUBTITLE_TRACK_SWITCH, data: TrackSwitchedData): void; + onSubtitleTrackLoaded(event: Events.SUBTITLE_TRACK_LOADED, data: TrackLoadedData): void; + _handleFragmentLoadComplete(fragLoadedData: FragLoadedData): void; + doTick(): void; + protected getMaxBufferLength(mainBufferLength?: number): number; + protected loadFragment(frag: Fragment, level: Level, targetBufferTime: number): void; + get mediaBufferTimeRanges(): Bufferable; +} + +declare class SubtitleTrackController extends BasePlaylistController { + private media; + private tracks; + private groupId; + private tracksInGroup; + private trackId; + private selectDefaultTrack; + private queuedDefaultTrack; + private trackChangeListener; + private asyncPollTrackChange; + private useTextTrackPolling; + private subtitlePollingInterval; + private _subtitleDisplay; + constructor(hls: Hls); + destroy(): void; + get subtitleDisplay(): boolean; + set subtitleDisplay(value: boolean); + private registerListeners; + private unregisterListeners; + protected onMediaAttached(event: Events.MEDIA_ATTACHED, data: MediaAttachedData): void; + private pollTrackChange; + protected onMediaDetaching(): void; + protected onManifestLoading(): void; + protected onManifestParsed(event: Events.MANIFEST_PARSED, data: ManifestParsedData): void; + protected onSubtitleTrackLoaded(event: Events.SUBTITLE_TRACK_LOADED, data: TrackLoadedData): void; + protected onLevelLoading(event: Events.LEVEL_LOADING, data: LevelLoadingData): void; + protected onLevelSwitching(event: Events.LEVEL_SWITCHING, data: LevelSwitchingData): void; + private switchLevel; + private findTrackId; + protected onError(event: Events.ERROR, data: ErrorData): void; + get allSubtitleTracks(): MediaPlaylist[]; + /** get alternate subtitle tracks list from playlist **/ + get subtitleTracks(): MediaPlaylist[]; + /** get/set index of the selected subtitle track (based on index in subtitle track lists) **/ + get subtitleTrack(): number; + set subtitleTrack(newId: number); + protected loadPlaylist(hlsUrlParameters?: HlsUrlParameters): void; + /** + * Disables the old subtitleTrack and sets current mode on the next subtitleTrack. + * This operates on the DOM textTracks. + * A value of -1 will disable all subtitle tracks. + */ + private toggleTrackModes; + /** + * This method is responsible for validating the subtitle index and periodically reloading if live. + * Dispatches the SUBTITLE_TRACK_SWITCH event, which instructs the subtitle-stream-controller to load the selected track. + */ + private setSubtitleTrack; + private onTextTracksChanged; +} + +declare interface SubtitleTrackLoadedData extends TrackLoadedData { +} + +declare interface SubtitleTracksUpdatedData { + subtitleTracks: MediaPlaylist[]; +} + +declare interface SubtitleTrackSwitchData { + id: number; + name?: string; + groupId?: string; + type?: MediaPlaylistType | 'main'; + url?: string; +} + +/** + * @ignore + * Sub-class specialization of EventHandler base class. + * + * TaskLoop allows to schedule a task function being called (optionnaly repeatedly) on the main loop, + * scheduled asynchroneously, avoiding recursive calls in the same tick. + * + * The task itself is implemented in `doTick`. It can be requested and called for single execution + * using the `tick` method. + * + * It will be assured that the task execution method (`tick`) only gets called once per main loop "tick", + * no matter how often it gets requested for execution. Execution in further ticks will be scheduled accordingly. + * + * If further execution requests have already been scheduled on the next tick, it can be checked with `hasNextTick`, + * and cancelled with `clearNextTick`. + * + * The task can be scheduled as an interval repeatedly with a period as parameter (see `setInterval`, `clearInterval`). + * + * Sub-classes need to implement the `doTick` method which will effectively have the task execution routine. + * + * Further explanations: + * + * The baseclass has a `tick` method that will schedule the doTick call. It may be called synchroneously + * only for a stack-depth of one. On re-entrant calls, sub-sequent calls are scheduled for next main loop ticks. + * + * When the task execution (`tick` method) is called in re-entrant way this is detected and + * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further + * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo). + */ +declare class TaskLoop { + private readonly _boundTick; + private _tickTimer; + private _tickInterval; + private _tickCallCount; + constructor(); + destroy(): void; + protected onHandlerDestroying(): void; + protected onHandlerDestroyed(): void; + hasInterval(): boolean; + hasNextTick(): boolean; + /** + * @param millis - Interval time (ms) + * @eturns True when interval has been scheduled, false when already scheduled (no effect) + */ + setInterval(millis: number): boolean; + /** + * @returns True when interval was cleared, false when none was set (no effect) + */ + clearInterval(): boolean; + /** + * @returns True when timeout was cleared, false when none was set (no effect) + */ + clearNextTick(): boolean; + /** + * Will call the subclass doTick implementation in this main loop tick + * or in the next one (via setTimeout(,0)) in case it has already been called + * in this tick (in case this is a re-entrant call). + */ + tick(): void; + tickImmediate(): void; + /** + * For subclass to implement task logic + * @abstract + */ + protected doTick(): void; +} + +declare class TimelineController implements ComponentAPI { + private hls; + private media; + private config; + private enabled; + private Cues; + private textTracks; + private tracks; + private initPTS; + private unparsedVttFrags; + private captionsTracks; + private nonNativeCaptionsTracks; + private cea608Parser1?; + private cea608Parser2?; + private lastCc; + private lastSn; + private lastPartIndex; + private prevCC; + private vttCCs; + private captionsProperties; + constructor(hls: Hls); + destroy(): void; + private lazyInit608; + addCues(trackName: string, startTime: number, endTime: number, screen: CaptionScreen, cueRanges: Array<[number, number]>): void; + private onInitPtsFound; + private getExistingTrack; + createCaptionsTrack(trackName: string): void; + private createNativeTrack; + private createNonNativeTrack; + private createTextTrack; + private onMediaAttaching; + private onMediaDetaching; + private onManifestLoading; + private _cleanTracks; + private onSubtitleTracksUpdated; + private _captionsOrSubtitlesFromCharacteristics; + private onManifestLoaded; + private closedCaptionsForLevel; + private onFragLoading; + private onFragLoaded; + private _parseIMSC1; + private _parseVTTs; + private _fallbackToIMSC1; + private _appendCues; + private onFragDecrypted; + private onSubtitleTracksCleared; + private onFragParsingUserdata; + onBufferFlushing(event: Events.BUFFER_FLUSHING, { startOffset, endOffset, endOffsetSubtitles, type }: BufferFlushingData): void; + private extractCea608Data; +} + +declare type TimelineControllerConfig = { + cueHandler: CuesInterface; + enableWebVTT: boolean; + enableIMSC1: boolean; + enableCEA708Captions: boolean; + captionsTextTrack1Label: string; + captionsTextTrack1LanguageCode: string; + captionsTextTrack2Label: string; + captionsTextTrack2LanguageCode: string; + captionsTextTrack3Label: string; + captionsTextTrack3LanguageCode: string; + captionsTextTrack4Label: string; + captionsTextTrack4LanguageCode: string; + renderTextTracksNatively: boolean; +}; + +declare interface Track { + id: 'audio' | 'main'; + buffer?: SourceBuffer; + container: string; + codec?: string; + initSegment?: Uint8Array; + levelCodec?: string; + metadata?: any; +} + +declare interface TrackLoadedData { + details: LevelDetails; + id: number; + groupId: string; + networkDetails: any; + stats: LoaderStats; + deliveryDirectives: HlsUrlParameters | null; +} + +declare interface TrackLoadingData { + id: number; + groupId: string; + url: string; + deliveryDirectives: HlsUrlParameters | null; +} + +declare interface TrackSet { + audio?: Track; + video?: Track; + audiovideo?: Track; +} + +declare interface TrackSwitchedData { + id: number; +} + +declare class TransmuxerInterface { + error: Error | null; + private hls; + private id; + private observer; + private frag; + private part; + private useWorker; + private workerContext; + private onwmsg?; + private transmuxer; + private onTransmuxComplete; + private onFlush; + constructor(hls: Hls, id: PlaylistLevelType, onTransmuxComplete: (transmuxResult: TransmuxerResult) => void, onFlush: (chunkMeta: ChunkMetadata) => void); + resetWorker(): void; + destroy(): void; + push(data: ArrayBuffer, initSegmentData: Uint8Array | undefined, audioCodec: string | undefined, videoCodec: string | undefined, frag: Fragment, part: Part | null, duration: number, accurateTimeOffset: boolean, chunkMeta: ChunkMetadata, defaultInitPTS?: RationalTimestamp): void; + flush(chunkMeta: ChunkMetadata): void; + private transmuxerError; + private handleFlushResult; + private onWorkerMessage; + private configureTransmuxer; + private handleTransmuxComplete; +} + +declare interface TransmuxerResult { + remuxResult: RemuxerResult; + chunkMeta: ChunkMetadata; +} + +declare type TSDemuxerConfig = { + forceKeyFrameOnDiscontinuity: boolean; +}; + +declare type UriReplacement = { + HOST?: string; + PARAMS?: { + [queryParameter: string]: string; + }; + 'PER-VARIANT-URIS'?: { + [stableVariantId: string]: string; + }; + 'PER-RENDITION-URIS'?: { + [stableRenditionId: string]: string; + }; +}; + +declare interface UserdataSample { + pts: number; + bytes?: Uint8Array; + type?: number; + payloadType?: number; + uuid?: string; + userData?: string; + userDataBytes?: Uint8Array; +} + +declare type VariableMap = Record; + +declare const enum VerboseLevel { + ERROR = 0, + TEXT = 1, + WARNING = 2, + INFO = 2, + DEBUG = 3, + DATA = 3 +} + +declare type VideoRange = (typeof VideoRangeValues)[number]; + +declare const VideoRangeValues: readonly ["SDR", "PQ", "HLG"]; + +interface AudioEvents { + ABORT: 'abort'; + TIME_UPDATE: 'timeupdate'; + CAN_PLAY: 'canplay'; + CAN_PLAY_THROUGH: 'canplaythrough'; + DURATION_CHANGE: 'durationchange'; + ENDED: 'ended'; + EMPTIED: 'emptied'; + PLAYING: 'playing'; + WAITING: 'waiting'; + SEEKING: 'seeking'; + SEEKED: 'seeked'; + LOADED_META_DATA: 'loadedmetadata'; + LOADED_DATA: 'loadeddata'; + PLAY: 'play'; + PAUSE: 'pause'; + RATE_CHANGE: 'ratechange'; + VOLUME_CHANGE: 'volumechange'; + SUSPEND: 'suspend'; + STALLED: 'stalled'; + PROGRESS: 'progress'; + LOAD_START: 'loadstart'; + ERROR: 'error'; + TRACK_CHANGE: 'trackchange'; +} +interface CustomAudioState { + AUDIO_X_STATE: 'AUDIO_X_STATE'; +} +type EventListenersList = Array | Array; +type EventListenerCallbackMap = { + [key in keyof Partial]: (e: Event, audioInstance: HTMLAudioElement, playLogEnabled: boolean) => void; +}; + +type InitMode = 'REACT' | 'VANILLA'; +type PlaybackRate = 1.0 | 1.25 | 1.5 | 1.75 | 2.0 | 2.5 | 3.0; +type Preload = 'none' | 'metadata' | 'auto' | ''; +type PlayBackState = 'idle' | 'playing' | 'ended' | 'ready' | 'paused' | 'stalled' | 'error' | 'buffering'; +type MediaArtwork = { + src: string; + name?: string; + sizes?: string; +}; +interface MediaTrack { + title: string; + source: string; + artwork: MediaArtwork[] | null; + duration?: number; + genre?: string; + album?: string; + comment?: string; + year?: number | string; + artist?: string; +} +interface AudioInit { + mode: InitMode; + useDefaultEventListeners: boolean; + showNotificationActions?: boolean; + preloadStrategy?: Preload; + playbackRate?: PlaybackRate; + customEventListeners?: EventListenerCallbackMap | null; + autoPlay?: boolean; + enablePlayLog?: boolean; + enableHls?: boolean; + enableEQ?: boolean; + crossOrigin?: string; + hlsConfig?: HlsConfig | {}; +} +interface AudioError { + code: number | string | null; + message: string; + readable: string; +} +interface AudioState { + playbackState: PlayBackState; + duration: number | undefined; + bufferedDuration: number; + progress: number | undefined; + volume: number; + playbackRate: PlaybackRate; + error: AudioError; + currentTrack: MediaTrack; + currentTrackPlayTime: number; + previousTrackPlayTime: number; +} + +interface ReadyState { + HAVE_NOTHING: 0; + HAVE_METADATA: 1; + HAVE_CURRENT_DATA: 2; + HAVE_FUTURE_DATA: 3; + HAVE_ENOUGH_DATA: 4; +} + +interface Band { + frequency: number; + type: BiquadFilterType; + gain: number; +} +interface Preset { + id: string | number; + name: string; + gains: number[]; +} +type EqualizerStatus = 'ACTIVE' | 'FAILED' | 'IDEAL'; + +interface ErrorEvents { + 1: 'MEDIA_ERR_ABORTED'; + 3: 'MEDIA_ERR_DECODE'; + 2: 'MEDIA_ERR_NETWORK'; + 4: 'MEDIA_ERR_SRC_NOT_SUPPORTED'; +} + +interface NetworkState { + 0: 'NETWORK_EMPTY'; + 1: 'NETWORK_IDLE'; + 2: 'NETWORK_LOADING'; + 3: 'NETWORK_NO_SOURCE'; +} + +declare class AudioX { + private _audio; + private isPlayLogEnabled; + private static _instance; + private eqStatus; + private isEqEnabled; + private eqInstance; + constructor(); + init(initProps: AudioInit): Promise; + addMedia(mediaTrack: MediaTrack): Promise; + attachEq(): void; + play(): Promise; + addMediaAndPlay(mediaTrack: MediaTrack): Promise; + pause(): void; + stop(): void; + reset(): Promise; + setVolume(volume: number): void; + setPlaybackRate(playbackRate: PlaybackRate): void; + mute(): void; + seek(time: number): void; + destroy(): Promise; + subscribe(eventName: string, callback: (data: any) => void, state?: any): () => void; + attachEventListeners(eventListenersList: EventListenersList): void; + getPresets(): Preset[]; + setPreset(id: keyof Preset): void; + setCustomEQ(gains: number[]): void; + get id(): string | null; + static getAudioInstance(): HTMLAudioElement; +} + +declare const AUDIO_X_CONSTANTS: Readonly<{ + REACT: InitMode; + VANILLA: InitMode; + DEVELOPMENT: "development"; +}>; + +declare const AUDIO_EVENTS: AudioEvents; + +declare const AUDIO_STATE: AudioState; + +export { AUDIO_EVENTS, AUDIO_STATE, AUDIO_X_CONSTANTS, type AudioError, type AudioEvents, type AudioInit, type AudioState, AudioX, type Band, type EqualizerStatus, type ErrorEvents, type EventListenerCallbackMap, type EventListenersList, type InitMode, type MediaArtwork, type MediaTrack, type NetworkState, type PlayBackState, type PlaybackRate, type Preset, type ReadyState }; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..9566356 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,5 @@ +var H=Object.defineProperty;var J=(a,e,t)=>e in a?H(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var r=(a,e)=>H(a,"name",{value:e,configurable:!0});var c=(a,e,t)=>(J(a,typeof e!="symbol"?e+"":e,t),t);var w=[{frequency:31,type:"lowshelf",gain:0},{frequency:63,type:"peaking",gain:0},{frequency:125,type:"peaking",gain:0},{frequency:250,type:"peaking",gain:0},{frequency:500,type:"peaking",gain:0},{frequency:1e3,type:"peaking",gain:0},{frequency:2e3,type:"peaking",gain:0},{frequency:4e3,type:"peaking",gain:0},{frequency:8e3,type:"peaking",gain:0},{frequency:16e3,type:"highshelf",gain:0}],O=[{id:"preset_default",name:"Default",gains:[0,0,0,0,0,0,0,0,0,0]},{id:"preset_live",name:"Live",gains:[-1,1,3,4,4,4,3,2,2,2]},{id:"preset_acoustic",name:"Acoustic",gains:[6,6,4,1,3,3,4,5,4,1.5]},{id:"preset_classical",name:"Classical",gains:[6,5,4,3,-1,-1,0,2,4,5]},{id:"preset_piano",name:"Piano",gains:[4,2,0,3.5,4,1.5,5,6,4,4.5]},{id:"preset_lounge",name:"Lounge",gains:[-3,-1.5,0,1,5.5,1,0,-1.5,2,.5]},{id:"preset_spoken_word",name:"Spoken Word",gains:[-2,0,0,1,5,6.5,7,6,3,0]},{id:"preset_jazz",name:"Jazz",gains:[5.5,4,1,2,-1.5,-1.5,0,1,4,5.5]},{id:"preset_pop",name:"Pop",gains:[.5,2.4,3.8,4.3,3,0,-.5,-.5,.5,.5]},{id:"preset_dance",name:"Dance",gains:[5,10,6.5,0,2,4.5,7.5,7,5.5,0]},{id:"preset_latin",name:"Latin",gains:[3.5,1.5,0,0,-1.5,-1.5,-1.5,0,4,6.5]},{id:"preset_rnb",name:"RnB",gains:[3.5,10.5,8.5,1,-3,-1.5,3,3.5,4,5]},{id:"preset_hiphop",name:"HipHop",gains:[7,6,1,4,-1,-.5,1,-.5,2,4]},{id:"preset_electronic",name:"Electronic",gains:[6,5.5,1,0,-2,2,1,1.5,5.5,6.5]},{id:"preset_techno",name:"Techno",gains:[3.8,2.4,0,-2.4,-1.9,0,3.8,4.8,4.8,4.3]},{id:"preset_deep",name:"Deep",gains:[6,5,1.5,.5,4,3,1.5,-2,-5,-6.5]},{id:"preset_club",name:"Club",gains:[0,0,3.8,2.4,2.4,2.4,1,0,0,0]},{id:"preset_rock",name:"Rock",gains:[7,5.5,4,1,-.5,0,.5,3,4.5,6.5]},{id:"preset_rock_soft",name:"Rock Soft",gains:[1.5,0,0,-.5,0,1,3.8,4.8,5.7,6.2]},{id:"preset_ska",name:"Ska",gains:[-.5,-1.5,-1,0,1,2,3.8,4.3,5.2,4.3]},{id:"preset_reggae",name:"Reggae",gains:[0,0,0,-2.4,0,2.5,2.5,0,0,0]},{id:"preset_country",name:"Country",gains:[3,2,1,0,-1,0,2,3,4,4]},{id:"preset_funk",name:"Funk",gains:[4,5,3,0,-1,0,2,4,5,5]},{id:"preset_blues",name:"Blues",gains:[2,1,0,-1,0,1,2,3,4,3]},{id:"preset_metal",name:"Metal",gains:[8,7,6,4,2,1,0,2,4,6]},{id:"preset_indie",name:"Indie",gains:[2,3,2,1,0,-1,-2,0,3,4]},{id:"preset_chill",name:"Chill",gains:[1,1,0,-1,-2,-1,1,2,3,2]},{id:"preset_world",name:"World",gains:[3,2,0,-2,-1,1,3,4,5,3]},{id:"preset_alternative",name:"Alternative",gains:[3,2,1,0,-1,-2,1,3,4,3]},{id:"preset_ambient",name:"Ambient",gains:[0,-1,-2,-3,-2,0,1,2,3,2]},{id:"preset_mellow",name:"Mellow",gains:[1,1,0,-1,-2,-1,1,2,3,1]},{id:"preset_grunge",name:"Grunge",gains:[5,4,3,2,1,0,0,2,4,5]},{id:"preset_soul",name:"Soul",gains:[3,3,2,1,0,-1,0,2,3,3]},{id:"preset_folk",name:"Folk",gains:[2,1,0,-1,-2,-1,1,2,3,2]},{id:"preset_trap",name:"Trap",gains:[7,6,3,1,-2,-1,1,3,6,7]},{id:"preset_dubstep",name:"Dubstep",gains:[6,5,4,3,2,1,1,3,5,6]}];var N=Object.freeze({REACT:"REACT",VANILLA:"VANILLA",DEVELOPMENT:"development"}),E=Object.freeze({BUFFERING:"buffering",PLAYING:"playing",PAUSED:"paused",READY:"ready",IDLE:"idle",ENDED:"ended",STALLED:"stalled",ERROR:"error",TRACK_CHANGE:"trackchanged"}),S=Object.freeze({MEDIA_ERR_ABORTED:"The user canceled the audio.",MEDIA_ERR_DECODE:"An error occurred while decoding the audio.",MEDIA_ERR_NETWORK:"A network error occurred while fetching the audio.",MEDIA_ERR_SRC_NOT_SUPPORTED:"The audio is missing or is in a format not supported by your browser.",DEFAULT:"An unknown error occurred."}),k={HLS:"https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js"};var l,Z=(l=class{static validateEventName(e){if(!e||typeof e!="string")throw new Error("Invalid event name")}static notify(e,t,s="audiox_notifier_default"){this.validateEventName(e);let n=l.listeners[e];n&&t!==null&&(l.notifierState[e]={...l.notifierState[e]||{},...t},n.forEach(i=>{i(l.notifierState[e]);}));}static listen(e,t,s={}){if(this.validateEventName(e),typeof t!="function")throw new Error("Callback must be a function");return l.listeners[e]?l.listeners[e].add(t):(l.notifierState[e]=s,l.listeners[e]=new Set([t])),()=>{let n=l.listeners[e];n&&(n.delete(t),n.size===0&&delete l.listeners[e]);}}static multiListen(e,t,s={}){if(this.validateEventName(e),!Array.isArray(t)||t.length===0)throw new Error("Callbacks must be a non-empty array of functions");let n=t.map(i=>l.listen(e,i,s));return ()=>{n.forEach(i=>i());}}static getLatestState(e){return this.validateEventName(e),l.notifierState[e]}},r(l,"ChangeNotifier"),c(l,"listeners",{}),c(l,"notifierState",{}),l),A=Z;var D=r(a=>a&&Array.isArray(a)&&a.length,"isValidArray");var x={},M=r(a=>{let e="";switch(a.error?.code){case MediaError.MEDIA_ERR_ABORTED:e+=S.MEDIA_ERR_ABORTED;break;case MediaError.MEDIA_ERR_NETWORK:e+=S.MEDIA_ERR_NETWORK;break;case MediaError.MEDIA_ERR_DECODE:e+=S.MEDIA_ERR_DECODE;break;case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:e+=S.MEDIA_ERR_SRC_NOT_SUPPORTED;break;default:e+=S.DEFAULT;break}return e},"getReadableErrorMessage"),G=r(a=>{let{title:e,album:t,artist:s,artwork:n}=a,i=n?n[0]?.src:"",g=["96x96","128x128","192x192","256x256","384x384","512x512"].map(L=>({src:i,sizes:L,type:"image/png"}));return {title:e,album:t,artist:s,artwork:g}},"metaDataCreator"),U=0,R=r((a,e)=>{let t=new Set;for(let i=0;ii+d,0);U=["ENDED","TRACK_CHANGE","PAUSE"].includes(e)?n:U,A.notify("AUDIO_STATE",{currentTrackPlayTime:n,previousTrackPlayTime:U});},"calculateActualPlayedLength"),v=r((a,e,t)=>new Promise((s,n)=>{if(window instanceof Window&&window.document)if(x[t])e(),s();else {x[t]=!0;let i=document.createElement("script");i.type="text/javascript",i.src=a,i.async=!0,i.onload=()=>{e(),s();},document.head.appendChild(i);}else n(`Window not ready unable to initialize ${t}`);}),"loadScript");var p,b=(p=class{constructor(){c(this,"audioCtx");c(this,"audioCtxStatus");c(this,"eqFilterBands");if(p._instance)return p._instance;if(this.audioCtx===void 0&&typeof AudioContext<"u")if(typeof AudioContext<"u")this.audioCtx=new AudioContext,this.audioCtxStatus="ACTIVE",this.init();else if(typeof window.webkitAudioContext<"u")this.audioCtx=new window.webkitAudioContext,this.audioCtxStatus="ACTIVE",this.init();else throw new Error("Web Audio API is not supported in this browser.");else this.audioCtxStatus="FAILED";if(this.audioCtxStatus==="ACTIVE"&&this.audioCtx.state==="suspended"){var e=r(()=>{this.audioCtx.resume(),setTimeout(()=>{this.audioCtx.state==="running"&&document.body.removeEventListener("click",e,!1);},0);},"resume");document.body.addEventListener("click",e,!1);}p._instance=this;}init(){try{let e=u.getAudioInstance(),t=this.audioCtx.createMediaElementSource(e),s=w.map(i=>{let d=this.audioCtx.createBiquadFilter();return d.type=i.type,d.frequency.value=i.frequency,d.gain.value=i.gain,d.Q.value=1,d}),n=this.audioCtx.createGain();n.gain.value=1,t.connect(s[0]);for(let i=0;is.id===e);if(!(!this.eqFilterBands||this.eqFilterBands.length!==t?.gains.length))for(let s=0;s{t.gain.value=e[s];});}},r(p,"Equalizer"),c(p,"_instance"),p);var B={ERROR:(a,e)=>{let t=e.type,s=e.details,n=e.fatal;A.notify("AUDIO_STATE",{playbackState:E.ERROR,error:{type:t,isFatal:n,detail:s}},`audiox_baseEvents_state_${a.type}`);},FRAG_CHANGED:()=>{}};var m=Object.freeze({ABORT:"abort",TIME_UPDATE:"timeupdate",CAN_PLAY:"canplay",CAN_PLAY_THROUGH:"canplaythrough",DURATION_CHANGE:"durationchange",ENDED:"ended",EMPTIED:"emptied",PLAYING:"playing",WAITING:"waiting",SEEKING:"seeking",SEEKED:"seeked",LOADED_META_DATA:"loadedmetadata",LOADED_DATA:"loadeddata",PLAY:"play",PAUSE:"pause",RATE_CHANGE:"ratechange",VOLUME_CHANGE:"volumechange",SUSPEND:"suspend",STALLED:"stalled",PROGRESS:"progress",LOAD_START:"loadstart",ERROR:"error",TRACK_CHANGE:"trackchange"}),V={MEDIA_ATTACHING:"hlsMediaAttaching",MEDIA_ATTACHED:"hlsMediaAttached",MEDIA_DETACHING:"hlsMediaDetaching",MEDIA_DETACHED:"hlsMediaDetached",BUFFER_RESET:"hlsBufferReset",BUFFER_CODECS:"hlsBufferCodecs",BUFFER_CREATED:"hlsBufferCreated",BUFFER_APPENDING:"hlsBufferAppending",BUFFER_APPENDED:"hlsBufferAppended",BUFFER_EOS:"hlsBufferEos",BUFFER_FLUSHING:"hlsBufferFlushing",BUFFER_FLUSHED:"hlsBufferFlushed",MANIFEST_LOADING:"hlsManifestLoading",MANIFEST_LOADED:"hlsManifestLoaded",MANIFEST_PARSED:"hlsManifestParsed",LEVEL_SWITCHING:"hlsLevelSwitching",LEVEL_SWITCHED:"hlsLevelSwitched",LEVEL_LOADING:"hlsLevelLoading",LEVEL_LOADED:"hlsLevelLoaded",LEVEL_UPDATED:"hlsLevelUpdated",LEVEL_PTS_UPDATED:"hlsLevelPtsUpdated",LEVELS_UPDATED:"hlsLevelsUpdated",AUDIO_TRACKS_UPDATED:"hlsAudioTracksUpdated",AUDIO_TRACK_SWITCHING:"hlsAudioTrackSwitching",AUDIO_TRACK_SWITCHED:"hlsAudioTrackSwitched",AUDIO_TRACK_LOADING:"hlsAudioTrackLoading",AUDIO_TRACK_LOADED:"hlsAudioTrackLoaded",SUBTITLE_TRACKS_UPDATED:"hlsSubtitleTracksUpdated",SUBTITLE_TRACKS_CLEARED:"hlsSubtitleTracksCleared",SUBTITLE_TRACK_SWITCH:"hlsSubtitleTrackSwitch",SUBTITLE_TRACK_LOADING:"hlsSubtitleTrackLoading",SUBTITLE_TRACK_LOADED:"hlsSubtitleTrackLoaded",SUBTITLE_FRAG_PROCESSED:"hlsSubtitleFragProcessed",CUES_PARSED:"hlsCuesParsed",NON_NATIVE_TEXT_TRACKS_FOUND:"hlsNonNativeTextTracksFound",INIT_PTS_FOUND:"hlsInitPtsFound",FRAG_LOADING:"hlsFragLoading",FRAG_LOAD_EMERGENCY_ABORTED:"hlsFragLoadEmergencyAborted",FRAG_LOADED:"hlsFragLoaded",FRAG_DECRYPTED:"hlsFragDecrypted",FRAG_PARSING_INIT_SEGMENT:"hlsFragParsingInitSegment",FRAG_PARSING_USERDATA:"hlsFragParsingUserdata",FRAG_PARSING_METADATA:"hlsFragParsingMetadata",FRAG_PARSED:"hlsFragParsed",FRAG_BUFFERED:"hlsFragBuffered",FRAG_CHANGED:"hlsFragChanged",FPS_DROP:"hlsFpsDrop",FPS_DROP_LEVEL_CAPPING:"hlsFpsDropLevelCapping",ERROR:"hlsError",DESTROYING:"hlsDestroying",KEY_LOADING:"hlsKeyLoading",KEY_LOADED:"hlsKeyLoaded",LIVE_BACK_BUFFER_REACHED:"hlsLiveBackBufferReached",BACK_BUFFER_REACHED:"hlsBackBufferReached"};var q=r((a,e=!1)=>{let t=u.getAudioInstance();D(Object.keys(a))&&Object.keys(a).forEach(s=>{let n=s;t?.addEventListener(m[n],i=>{if(s&&a[n]){let d=a[n];typeof d=="function"&&d(i,t,e);}});});},"attachDefaultEventListeners"),K=r((a,e=!1)=>{let t=u.getAudioInstance();D(a)&&a.forEach(s=>{let n=s;Object.keys(m).includes(n)&&t?.addEventListener(m[n],i=>{A.notify(m[n],{e:i,audioInstance:t,enablePlayLog:e});});});},"attachCustomEventListeners"),Y=r((a,e=!1)=>{let s=new y().getHlsInstance();D(Object.keys(a))&&Object.keys(a).forEach(n=>{let i=n;s.on(V[i],(d,g)=>{if(i&&a[i]){let h=a[i];typeof h=="function"&&h(d,g,s,e);}});});},"attachHlsEventsListeners");var I,T,ee=(T=class{constructor(){c(this,"HlsClass");if(T._instance)return T._instance;T._instance=this;}async load(){return await v(k.HLS,()=>{},"hls").then(()=>{this.HlsClass=window.Hls,window.Hls=void 0;}).catch(e=>{}),this.HlsClass}async init(e={},t){let s=await this.load();s.isSupported()&&(I=new s(e),Y(B,t));}addHlsMedia(e){let t=this.HlsClass,s=u.getAudioInstance();I.attachMedia(s),I.on(t.Events.MEDIA_ATTACHED,function(){I.loadSource(e.source);});}getHlsInstance(){return I}},r(T,"HlsAdapter"),c(T,"_instance"),T),y=ee;var z=Object.freeze({1:"MEDIA_ERR_ABORTED",3:"MEDIA_ERR_DECODE",2:"MEDIA_ERR_NETWORK",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"});var _=A,X={LOADED_META_DATA:(a,e)=>{_.notify("AUDIO_STATE",{playbackState:E.BUFFERING,duration:e?.duration,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_state_${a.type}`);},CAN_PLAY:a=>{_.notify("AUDIO_STATE",{playbackState:E.BUFFERING,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`);},CAN_PLAY_THROUGH:a=>{_.notify("AUDIO_STATE",{playbackState:E.READY,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`);},PLAY:(a,e)=>{_.notify("AUDIO_STATE",{playbackState:E.PLAYING,progress:e?.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`);},PAUSE:(a,e,t)=>{_.notify("AUDIO_STATE",{playbackState:E.PAUSED,progress:e?.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`),t&&R(e,"PAUSE");},ENDED:(a,e,t)=>{_.notify("AUDIO_STATE",{playbackState:E.ENDED,progress:e?.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`),t&&R(e,"ENDED");},ERROR:(a,e)=>{let t=e.error?.code,s=M(e);_.notify("AUDIO_STATE",{playbackState:E.ERROR,error:{code:t,message:z[t],readable:s}},`audiox_baseEvents_state_${a.type}`);},TIME_UPDATE:(a,e)=>{let t=A.getLatestState("AUDIO_X_STATE");_.notify("AUDIO_STATE",{playbackState:e.paused?t.playbackState:E.PLAYING,progress:e?.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`);},WAITING:(a,e)=>{_.notify("AUDIO_STATE",{playbackState:E.BUFFERING,progress:e?.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${a.type}`);},VOLUME_CHANGE:a=>{_.notify("AUDIO_STATE",{},"audiox_baseEvents_state");}};var j=r(a=>{"mediaSession"in navigator&&(navigator.mediaSession.metadata=new MediaMetadata(G(a)));},"updateMetaData"),W=r(()=>{"mediaSession"in navigator&&(navigator.mediaSession.setActionHandler("play",()=>{u.getAudioInstance().play();}),navigator.mediaSession.setActionHandler("pause",()=>{u.getAudioInstance().pause();}));},"attachMediaSessionHandlers");var F={HAVE_NOTHING:0,HAVE_METADATA:1,HAVE_CURRENT_DATA:2,HAVE_FUTURE_DATA:3,HAVE_ENOUGH_DATA:4},P={playbackState:E.IDLE,duration:0,bufferedDuration:0,progress:0,volume:50,playbackRate:1,error:{code:null,message:"",readable:""},currentTrack:{},currentTrackPlayTime:0,previousTrackPlayTime:0};A.listen("AUDIO_STATE",a=>{A.notify("AUDIO_X_STATE",{...P,...a});},P);var o,C=A,f,u=(f=class{constructor(){c(this,"_audio");c(this,"isPlayLogEnabled");c(this,"eqStatus","IDEAL");c(this,"isEqEnabled",!1);c(this,"eqInstance");if(f._instance)return f._instance;if(process.env.NODE_ENV!==N?.DEVELOPMENT&&o)throw new Error("Cannot create multiple audio instance");f._instance=this,this._audio=new Audio,o=this._audio;}async init(e){let{preloadStrategy:t="auto",autoPlay:s=!1,useDefaultEventListeners:n=!0,customEventListeners:i=null,showNotificationActions:d=!1,enablePlayLog:g=!1,enableHls:h=!1,enableEQ:L=!1,crossOrigin:$="anonymous",hlsConfig:Q={}}=e;this._audio?.setAttribute("id","audio_x_instance"),this._audio.preload=t,this._audio.autoplay=s,this._audio.crossOrigin=$,this.isPlayLogEnabled=g,(n||i==null)&&q(X,g),d&&W(),L&&(this.isEqEnabled=L),h&&new y().init(Q,g);}async addMedia(e){if(!e)return;let t=e.source.includes(".m3u8")?"HLS":"DEFAULT";if(this.isPlayLogEnabled&&R(o,"TRACK_CHANGE"),t==="HLS"){let s=new y,n=s.getHlsInstance();n?(n.detachMedia(),s.addHlsMedia(e)):await this.reset();}else o.src=e.source;C.notify("AUDIO_STATE",{playbackState:E.TRACK_CHANGE,currentTrackPlayTime:0,currentTrack:e}),j(e),o.load();}attachEq(){if(this.isEqEnabled&&this.eqStatus==="IDEAL")try{let e=new b;this.eqStatus=e.status(),this.eqInstance=e;}catch{}}async play(){let e=o.src!=="";o?.paused&&o.HAVE_ENOUGH_DATA===F.HAVE_ENOUGH_DATA&&e&&await o.play().then(()=>{}).catch(()=>{});}async addMediaAndPlay(e){try{e&&this.addMedia(e).then(()=>{o.HAVE_ENOUGH_DATA===F.HAVE_ENOUGH_DATA&&setTimeout(async()=>{this.attachEq(),await this.play();},950);});}catch{}}pause(){o&&!o?.paused&&o?.pause();}stop(){o&&!o.paused&&(o?.pause(),o.currentTime=0);}async reset(){o&&(this.stop(),o.src="",o.srcObject=null);}setVolume(e){let t=e/100;o&&(o.volume=t,C.notify("AUDIO_STATE",{volume:e}));}setPlaybackRate(e){o&&(o.playbackRate=e,C.notify("AUDIO_STATE",{playbackRate:e}));}mute(){o&&!o.muted&&(o.muted=!0);}seek(e){o&&(o.currentTime=e);}async destroy(){o&&(await this.reset(),o.removeAttribute("src"),o.load());}subscribe(e,t,s={}){return C.listen(e,t,s)}attachEventListeners(e){K(e);}getPresets(){return b.getPresets()}setPreset(e){this.eqInstance.setPreset(e);}setCustomEQ(e){this.eqInstance.setCustomEQ(e);}get id(){return o?.getAttribute("id")}static getAudioInstance(){return o}},r(f,"AudioX"),c(f,"_instance"),f); + +export { m as AUDIO_EVENTS, P as AUDIO_STATE, N as AUDIO_X_CONSTANTS, u as AudioX }; +//# sourceMappingURL=out.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..70e05eb --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/constants/equalizer.ts","../src/constants/common.ts","../src/helpers/notifier.ts","../src/helpers/common.ts","../src/adapters/equalizer.ts","../src/events/hlsEvents.ts","../src/events/audioEvents.ts","../src/events/listeners.ts","../src/adapters/hls.ts","../src/events/errorEvents.ts","../src/events/baseEvents.ts","../src/mediasession/mediasessionHandler.ts","../src/states/audioState.ts","../src/audio.ts"],"names":["bands","frequency","type","gain","presets","id","name","gains","AUDIO_X_CONSTANTS","Object","freeze","REACT","VANILLA","DEVELOPMENT","PLAYBACK_STATE","BUFFERING","PLAYING","PAUSED","READY","IDLE","ENDED","STALLED","ERROR","TRACK_CHANGE","ERROR_MSG_MAP","MEDIA_ERR_ABORTED","MEDIA_ERR_DECODE","MEDIA_ERR_NETWORK","MEDIA_ERR_SRC_NOT_SUPPORTED","DEFAULT","URLS","HLS","_a","ChangeNotifier","validateEventName","eventName","Error","notify","data","caller","listenerCbs","listeners","notifierState","forEach","cb","listen","callback","state","add","Set","eventListeners","delete","size","multiListen","callbacks","Array","isArray","length","unsubscribeFunctions","map","unsubscribe","getLatestState","__publicField","notifier_default","isValidArray","__name","arr","isValidWindow","window","undefined","Window","loadedScripts","getReadableErrorMessage","audioInstance","message","error","code","MediaError","metaDataCreator","mediaTrack","title","album","artist","artwork","artworkUrl","src","artworkMap","el","sizes","previousTrackPlayTime","calculateActualPlayedLength","event","lengthSet","i","played","startX","start","width","end","currentTrackPlayTime","reduce","acc","val","includes","loadScript","url","onLoad","Promise","resolve","reject","document","script","createElement","async","onload","head","appendChild","Equalizer","constructor","audioCtx","audioCtxStatus","eqFilterBands","_instance","AudioContext","init","webkitAudioContext","resume","setTimeout","body","removeEventListener","addEventListener","AudioX","getAudioInstance","audioSource","createMediaElementSource","equalizerBands","band","filter","createBiquadFilter","value","Q","gainNode","createGain","connect","destination","setPreset","preset","find","getPresets","status","setCustomEQ","index","HLS_EVENTS_CALLBACK_MAP","e","detail","details","isFatal","fatal","playbackState","FRAG_CHANGED","AUDIO_EVENTS","ABORT","TIME_UPDATE","CAN_PLAY","CAN_PLAY_THROUGH","DURATION_CHANGE","EMPTIED","WAITING","SEEKING","SEEKED","LOADED_META_DATA","LOADED_DATA","PLAY","PAUSE","RATE_CHANGE","VOLUME_CHANGE","SUSPEND","PROGRESS","LOAD_START","HLS_EVENTS","MEDIA_ATTACHING","MEDIA_ATTACHED","MEDIA_DETACHING","MEDIA_DETACHED","BUFFER_RESET","BUFFER_CODECS","BUFFER_CREATED","BUFFER_APPENDING","BUFFER_APPENDED","BUFFER_EOS","BUFFER_FLUSHING","BUFFER_FLUSHED","MANIFEST_LOADING","MANIFEST_LOADED","MANIFEST_PARSED","LEVEL_SWITCHING","LEVEL_SWITCHED","LEVEL_LOADING","LEVEL_LOADED","LEVEL_UPDATED","LEVEL_PTS_UPDATED","LEVELS_UPDATED","AUDIO_TRACKS_UPDATED","AUDIO_TRACK_SWITCHING","AUDIO_TRACK_SWITCHED","AUDIO_TRACK_LOADING","AUDIO_TRACK_LOADED","SUBTITLE_TRACKS_UPDATED","SUBTITLE_TRACKS_CLEARED","SUBTITLE_TRACK_SWITCH","SUBTITLE_TRACK_LOADING","SUBTITLE_TRACK_LOADED","SUBTITLE_FRAG_PROCESSED","CUES_PARSED","NON_NATIVE_TEXT_TRACKS_FOUND","INIT_PTS_FOUND","FRAG_LOADING","FRAG_LOAD_EMERGENCY_ABORTED","FRAG_LOADED","FRAG_DECRYPTED","FRAG_PARSING_INIT_SEGMENT","FRAG_PARSING_USERDATA","FRAG_PARSING_METADATA","FRAG_PARSED","FRAG_BUFFERED","FPS_DROP","FPS_DROP_LEVEL_CAPPING","DESTROYING","KEY_LOADING","KEY_LOADED","LIVE_BACK_BUFFER_REACHED","BACK_BUFFER_REACHED","CUSTOM_AUDIO_EVENTS","AUDIO_X_STATE","attachDefaultEventListeners","eventListenersCallbackMap","playLogEnabled","keys","evt","listenerCallback","attachCustomEventListeners","eventListenersList","enablePlayLog","attachHlsEventsListeners","hlsEventlistenerCallbackMap","hlsInstance","HlsAdapter","getHlsInstance","on","HlsClass","load","then","Hls","catch","msg","config","isSupported","addHlsMedia","attachMedia","Events","loadSource","source","hls_default","ERROR_EVENTS","notifier","BASE_EVENT_CALLBACK_MAP","duration","readable","progress","currentTime","errorCode","audioState","paused","updateMetaData","navigator","mediaSession","metadata","MediaMetadata","attachMediaSessionHandlers","setActionHandler","play","pause","READY_STATE","HAVE_NOTHING","HAVE_METADATA","HAVE_CURRENT_DATA","HAVE_FUTURE_DATA","HAVE_ENOUGH_DATA","AUDIO_STATE","bufferedDuration","volume","playbackRate","currentTrack","_audio","isPlayLogEnabled","eqStatus","isEqEnabled","eqInstance","process","env","NODE_ENV","Audio","initProps","preloadStrategy","autoPlay","useDefaultEventListeners","customEventListeners","showNotificationActions","enableHls","enableEQ","crossOrigin","hlsConfig","setAttribute","preload","autoplay","addMedia","mediaType","hls","detachMedia","reset","attachEq","eq","isSourceAvailable","addMediaAndPlay","stop","srcObject","setVolume","actualVolume","setPlaybackRate","mute","muted","seek","time","destroy","removeAttribute","subscribe","attachEventListeners","getAttribute"],"mappings":"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","sourcesContent":["import { Band, Preset } from 'types/equalizer.types';\n\nconst bands: Band[] = [\n { frequency: 31, type: 'lowshelf', gain: 0 }, // Band 0: 31 Hz - Low Shelf Filter\n { frequency: 63, type: 'peaking', gain: 0 }, // Band 1: 63 Hz - Peaking Filter\n { frequency: 125, type: 'peaking', gain: 0 }, // Band 2: 125 Hz - Peaking Filter\n { frequency: 250, type: 'peaking', gain: 0 }, // Band 3: 250 Hz - Peaking Filter\n { frequency: 500, type: 'peaking', gain: 0 }, // Band 4: 500 Hz - Peaking Filter\n { frequency: 1000, type: 'peaking', gain: 0 }, // Band 5: 1 kHz - Peaking Filter\n { frequency: 2000, type: 'peaking', gain: 0 }, // Band 6: 2 kHz - Peaking Filter\n { frequency: 4000, type: 'peaking', gain: 0 }, // Band 7: 4 kHz - Peaking Filter\n { frequency: 8000, type: 'peaking', gain: 0 }, // Band 8: 8 kHz - Peaking Filter\n { frequency: 16000, type: 'highshelf', gain: 0 } // Band 9: 16 kHz - High Shelf Filter\n];\n\nconst presets: Preset[] = [\n {\n id: 'preset_default',\n name: 'Default',\n gains: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]\n },\n {\n id: 'preset_live',\n name: 'Live',\n gains: [-1.0, 1.0, 3.0, 4.0, 4.0, 4.0, 3.0, 2.0, 2.0, 2.0]\n },\n {\n id: 'preset_acoustic',\n name: 'Acoustic',\n gains: [6.0, 6.0, 4.0, 1.0, 3.0, 3.0, 4.0, 5.0, 4.0, 1.5]\n },\n {\n id: 'preset_classical',\n name: 'Classical',\n gains: [6.0, 5.0, 4.0, 3.0, -1.0, -1.0, 0.0, 2.0, 4.0, 5.0]\n },\n {\n id: 'preset_piano',\n name: 'Piano',\n gains: [4.0, 2.0, 0.0, 3.5, 4.0, 1.5, 5.0, 6.0, 4.0, 4.5]\n },\n {\n id: 'preset_lounge',\n name: 'Lounge',\n gains: [-3.0, -1.5, 0.0, 1.0, 5.5, 1.0, 0.0, -1.5, 2.0, 0.5]\n },\n {\n id: 'preset_spoken_word',\n name: 'Spoken Word',\n gains: [-2.0, 0.0, 0.0, 1.0, 5.0, 6.5, 7.0, 6.0, 3.0, 0.0]\n },\n {\n id: 'preset_jazz',\n name: 'Jazz',\n gains: [5.5, 4.0, 1.0, 2.0, -1.5, -1.5, 0.0, 1.0, 4.0, 5.5]\n },\n {\n id: 'preset_pop',\n name: 'Pop',\n gains: [0.5, 2.4, 3.8, 4.3, 3.0, 0.0, -0.5, -0.5, 0.5, 0.5]\n },\n {\n id: 'preset_dance',\n name: 'Dance',\n gains: [5.0, 10.0, 6.5, 0.0, 2.0, 4.5, 7.5, 7.0, 5.5, 0.0]\n },\n {\n id: 'preset_latin',\n name: 'Latin',\n gains: [3.5, 1.5, 0.0, 0.0, -1.5, -1.5, -1.5, 0.0, 4.0, 6.5]\n },\n {\n id: 'preset_rnb',\n name: 'RnB',\n gains: [3.5, 10.5, 8.5, 1.0, -3.0, -1.5, 3.0, 3.5, 4.0, 5.0]\n },\n {\n id: 'preset_hiphop',\n name: 'HipHop',\n gains: [7.0, 6.0, 1.0, 4.0, -1.0, -0.5, 1.0, -0.5, 2.0, 4.0]\n },\n {\n id: 'preset_electronic',\n name: 'Electronic',\n gains: [6.0, 5.5, 1.0, 0.0, -2.0, 2.0, 1.0, 1.5, 5.5, 6.5]\n },\n {\n id: 'preset_techno',\n name: 'Techno',\n gains: [3.8, 2.4, 0.0, -2.4, -1.9, 0.0, 3.8, 4.8, 4.8, 4.3]\n },\n {\n id: 'preset_deep',\n name: 'Deep',\n gains: [6.0, 5.0, 1.5, 0.5, 4.0, 3.0, 1.5, -2.0, -5.0, -6.5]\n },\n {\n id: 'preset_club',\n name: 'Club',\n gains: [0.0, 0.0, 3.8, 2.4, 2.4, 2.4, 1.0, 0.0, 0.0, 0.0]\n },\n {\n id: 'preset_rock',\n name: 'Rock',\n gains: [7.0, 5.5, 4.0, 1.0, -0.5, 0.0, 0.5, 3.0, 4.5, 6.5]\n },\n {\n id: 'preset_rock_soft',\n name: 'Rock Soft',\n gains: [1.5, 0.0, 0.0, -0.5, 0.0, 1.0, 3.8, 4.8, 5.7, 6.2]\n },\n {\n id: 'preset_ska',\n name: 'Ska',\n gains: [-0.5, -1.5, -1.0, 0.0, 1.0, 2.0, 3.8, 4.3, 5.2, 4.3]\n },\n {\n id: 'preset_reggae',\n name: 'Reggae',\n gains: [0.0, 0.0, 0.0, -2.4, 0.0, 2.5, 2.5, 0.0, 0.0, 0.0]\n },\n {\n id: 'preset_country',\n name: 'Country',\n gains: [3.0, 2.0, 1.0, 0.0, -1.0, 0.0, 2.0, 3.0, 4.0, 4.0]\n },\n {\n id: 'preset_funk',\n name: 'Funk',\n gains: [4.0, 5.0, 3.0, 0.0, -1.0, 0.0, 2.0, 4.0, 5.0, 5.0]\n },\n {\n id: 'preset_blues',\n name: 'Blues',\n gains: [2.0, 1.0, 0.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 3.0]\n },\n {\n id: 'preset_metal',\n name: 'Metal',\n gains: [8.0, 7.0, 6.0, 4.0, 2.0, 1.0, 0.0, 2.0, 4.0, 6.0]\n },\n {\n id: 'preset_indie',\n name: 'Indie',\n gains: [2.0, 3.0, 2.0, 1.0, 0.0, -1.0, -2.0, 0.0, 3.0, 4.0]\n },\n {\n id: 'preset_chill',\n name: 'Chill',\n gains: [1.0, 1.0, 0.0, -1.0, -2.0, -1.0, 1.0, 2.0, 3.0, 2.0]\n },\n {\n id: 'preset_world',\n name: 'World',\n gains: [3.0, 2.0, 0.0, -2.0, -1.0, 1.0, 3.0, 4.0, 5.0, 3.0]\n },\n {\n id: 'preset_alternative',\n name: 'Alternative',\n gains: [3.0, 2.0, 1.0, 0.0, -1.0, -2.0, 1.0, 3.0, 4.0, 3.0]\n },\n {\n id: 'preset_ambient',\n name: 'Ambient',\n gains: [0.0, -1.0, -2.0, -3.0, -2.0, 0.0, 1.0, 2.0, 3.0, 2.0]\n },\n {\n id: 'preset_mellow',\n name: 'Mellow',\n gains: [1.0, 1.0, 0.0, -1.0, -2.0, -1.0, 1.0, 2.0, 3.0, 1.0]\n },\n {\n id: 'preset_grunge',\n name: 'Grunge',\n gains: [5.0, 4.0, 3.0, 2.0, 1.0, 0.0, 0.0, 2.0, 4.0, 5.0]\n },\n {\n id: 'preset_soul',\n name: 'Soul',\n gains: [3.0, 3.0, 2.0, 1.0, 0.0, -1.0, 0.0, 2.0, 3.0, 3.0]\n },\n {\n id: 'preset_folk',\n name: 'Folk',\n gains: [2.0, 1.0, 0.0, -1.0, -2.0, -1.0, 1.0, 2.0, 3.0, 2.0]\n },\n {\n id: 'preset_trap',\n name: 'Trap',\n gains: [7.0, 6.0, 3.0, 1.0, -2.0, -1.0, 1.0, 3.0, 6.0, 7.0]\n },\n {\n id: 'preset_dubstep',\n name: 'Dubstep',\n gains: [6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 1.0, 3.0, 5.0, 6.0]\n }\n];\n\nexport { bands, presets };\n","import { InitMode } from 'types';\nimport { ErrorMessageMap } from 'types/errorEvents.types';\n\nconst AUDIO_X_CONSTANTS = Object.freeze({\n REACT: 'REACT' as InitMode,\n VANILLA: 'VANILLA' as InitMode,\n DEVELOPMENT: 'development'\n});\n\nconst PLAYBACK_STATE = Object.freeze({\n BUFFERING: 'buffering',\n PLAYING: 'playing',\n PAUSED: 'paused',\n READY: 'ready',\n IDLE: 'idle',\n ENDED: 'ended',\n STALLED: 'stalled',\n ERROR: 'error',\n TRACK_CHANGE: 'trackchanged'\n});\n\nconst ERROR_MSG_MAP: ErrorMessageMap = Object.freeze({\n MEDIA_ERR_ABORTED: 'The user canceled the audio.',\n MEDIA_ERR_DECODE: 'An error occurred while decoding the audio.',\n MEDIA_ERR_NETWORK: 'A network error occurred while fetching the audio.',\n MEDIA_ERR_SRC_NOT_SUPPORTED:\n 'The audio is missing or is in a format not supported by your browser.',\n DEFAULT: 'An unknown error occurred.'\n});\n\nconst URLS = {\n HLS: 'https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js'\n};\n\nexport { AUDIO_X_CONSTANTS, ERROR_MSG_MAP, PLAYBACK_STATE, URLS };\n","type ListenerCallback = (data: T) => void;\n\nclass ChangeNotifier {\n private static listeners: Record>> = {};\n private static notifierState: Record = {};\n\n private static validateEventName(eventName: string): void {\n if (!eventName || typeof eventName !== 'string') {\n throw new Error('Invalid event name');\n }\n }\n\n static notify(\n eventName: string,\n data: T,\n caller: string = 'audiox_notifier_default'\n ): void {\n this.validateEventName(eventName);\n\n const listenerCbs = ChangeNotifier.listeners[eventName];\n\n if (!listenerCbs) return;\n\n if (data !== null) {\n console.log(`NOTIFYING TO EVENT : ${eventName} - CALLER : ${caller}`);\n\n ChangeNotifier.notifierState[eventName] = {\n ...(ChangeNotifier.notifierState[eventName] || {}),\n ...data\n };\n\n listenerCbs.forEach((cb: ListenerCallback) => {\n cb(ChangeNotifier.notifierState[eventName]);\n });\n }\n }\n\n static listen(\n eventName: string,\n callback: ListenerCallback,\n state = {}\n ): () => void {\n this.validateEventName(eventName);\n\n if (typeof callback !== 'function') {\n throw new Error('Callback must be a function');\n }\n\n if (!ChangeNotifier.listeners[eventName]) {\n ChangeNotifier.notifierState[eventName] = state;\n ChangeNotifier.listeners[eventName] = new Set([callback]);\n } else {\n ChangeNotifier.listeners[eventName].add(callback);\n }\n\n return (): void => {\n const eventListeners = ChangeNotifier.listeners[eventName];\n\n if (!eventListeners) {\n console.log(`EVENT NOT FOUND : ${eventName}`);\n return;\n }\n\n console.log(`REMOVING EVENT LISTENER FOR EVENT : ${eventName}`);\n\n eventListeners.delete(callback);\n\n if (eventListeners.size === 0) {\n delete ChangeNotifier.listeners[eventName];\n }\n };\n }\n\n static multiListen(\n eventName: string,\n callbacks: ListenerCallback[],\n state = {}\n ): () => void {\n this.validateEventName(eventName);\n\n if (!Array.isArray(callbacks) || callbacks.length === 0) {\n throw new Error('Callbacks must be a non-empty array of functions');\n }\n\n const unsubscribeFunctions = callbacks.map((callback) =>\n ChangeNotifier.listen(eventName, callback, state)\n );\n\n return (): void => {\n unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());\n };\n }\n\n // Retrieve the latest state data for a specific event\n static getLatestState(eventName: string): T | undefined {\n this.validateEventName(eventName);\n\n return ChangeNotifier.notifierState[eventName];\n }\n}\n\nexport default ChangeNotifier;\n","import { ERROR_MSG_MAP } from 'constants/common';\nimport { AudioEvents, MediaTrack } from 'types';\nimport ChangeNotifier from './notifier';\n\nconst isValidArray = (arr: any[]) => arr && Array.isArray(arr) && arr.length;\nconst isValidFunction = (fn: any) =>\n fn instanceof Function && typeof fn === 'function';\n\nconst isValidObject = (obj: any) =>\n typeof obj === 'object' &&\n obj !== null &&\n obj instanceof Object &&\n Object.keys(obj).length;\n\nconst isValidWindow = typeof window !== undefined && window instanceof Window;\nconst loadedScripts: any = {};\n\nconst getReadableErrorMessage = (audioInstance: HTMLAudioElement) => {\n let message = '';\n const err = audioInstance.error;\n\n switch (err?.code) {\n case MediaError.MEDIA_ERR_ABORTED:\n message += ERROR_MSG_MAP['MEDIA_ERR_ABORTED'];\n break;\n case MediaError.MEDIA_ERR_NETWORK:\n message += ERROR_MSG_MAP['MEDIA_ERR_NETWORK'];\n break;\n case MediaError.MEDIA_ERR_DECODE:\n message += ERROR_MSG_MAP['MEDIA_ERR_DECODE'];\n break;\n case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:\n message += ERROR_MSG_MAP['MEDIA_ERR_SRC_NOT_SUPPORTED'];\n break;\n default:\n message += ERROR_MSG_MAP['DEFAULT'];\n break;\n }\n\n return message;\n};\n\nconst metaDataCreator = (mediaTrack: MediaTrack) => {\n const { title, album, artist, artwork } = mediaTrack;\n const artworkUrl = artwork ? artwork[0]?.src : '';\n const sizes = [\n '96x96',\n '128x128',\n '192x192',\n '256x256',\n '384x384',\n '512x512'\n ];\n const artworkMap = sizes.map((el) => {\n return { src: artworkUrl, sizes: el, type: 'image/png' };\n });\n const metaData = {\n title,\n album,\n artist,\n artwork: artworkMap\n };\n return metaData;\n};\n\nlet previousTrackPlayTime = 0;\nexport const calculateActualPlayedLength = (\n audioInstance: HTMLAudioElement,\n event?: keyof AudioEvents\n) => {\n const lengthSet = new Set();\n for (let i = 0; i < audioInstance.played.length; i++) {\n const startX = audioInstance.played.start(i);\n const endX = audioInstance.played.end(i);\n const width = endX - startX;\n lengthSet.add(width);\n }\n const lengthArr = [...lengthSet] as number[];\n const currentTrackPlayTime = lengthArr.reduce((acc, val) => acc + val, 0);\n\n previousTrackPlayTime = ['ENDED', 'TRACK_CHANGE', 'PAUSE'].includes(\n event as keyof AudioEvents\n )\n ? currentTrackPlayTime\n : previousTrackPlayTime;\n ChangeNotifier.notify('AUDIO_STATE', {\n currentTrackPlayTime,\n previousTrackPlayTime\n });\n};\n\nconst loadScript = (\n url: string,\n onLoad: () => void,\n name: string\n): Promise => {\n return new Promise((resolve, reject) => {\n if (window instanceof Window && window.document) {\n if (!loadedScripts[name]) {\n loadedScripts[name] = true;\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = url;\n script.async = true;\n script.onload = () => {\n onLoad();\n resolve();\n };\n document.head.appendChild(script);\n } else {\n onLoad();\n resolve();\n }\n } else {\n reject(`Window not ready unable to initialize ${name}`);\n }\n });\n};\n\nexport {\n getReadableErrorMessage,\n isValidArray,\n isValidFunction,\n isValidObject,\n isValidWindow,\n loadScript,\n metaDataCreator\n};\n","import { AudioX } from 'audio';\nimport { bands, presets } from 'constants/equalizer';\nimport { isValidArray } from 'helpers/common';\n\nimport { EqualizerStatus, Preset } from 'types/equalizer.types';\n\nclass Equalizer {\n private static _instance: Equalizer;\n private audioCtx: AudioContext;\n private audioCtxStatus: EqualizerStatus;\n private eqFilterBands: BiquadFilterNode[];\n\n constructor() {\n if (Equalizer._instance) {\n console.warn(\n 'Instantiation failed: cannot create multiple instance of Equalizer returning existing instance'\n );\n return Equalizer._instance;\n }\n\n if (this.audioCtx === undefined && typeof AudioContext !== 'undefined') {\n if (typeof AudioContext !== 'undefined') {\n this.audioCtx = new AudioContext();\n this.audioCtxStatus = 'ACTIVE';\n this.init();\n } else if (typeof (window as any).webkitAudioContext !== 'undefined') {\n this.audioCtx = new (window as any).webkitAudioContext();\n this.audioCtxStatus = 'ACTIVE';\n this.init();\n } else {\n throw new Error('Web Audio API is not supported in this browser.');\n }\n } else {\n console.log('Equalizer not initialized, AudioContext failed');\n this.audioCtxStatus = 'FAILED';\n }\n\n // context state at this time is `undefined` in iOS8 Safari\n if (\n this.audioCtxStatus === 'ACTIVE' &&\n this.audioCtx.state === 'suspended'\n ) {\n var resume = () => {\n this.audioCtx.resume();\n setTimeout(() => {\n if (this.audioCtx.state === 'running') {\n document.body.removeEventListener('click', resume, false);\n }\n }, 0);\n };\n\n document.body.addEventListener('click', resume, false);\n }\n\n Equalizer._instance = this;\n }\n\n init() {\n try {\n const audioInstance = AudioX.getAudioInstance();\n const audioSource = this.audioCtx.createMediaElementSource(audioInstance);\n\n const equalizerBands = bands.map((band) => {\n const filter = this.audioCtx.createBiquadFilter();\n filter.type = band.type;\n filter.frequency.value = band.frequency;\n filter.gain.value = band.gain;\n filter.Q.value = 1;\n return filter;\n });\n\n const gainNode = this.audioCtx.createGain();\n gainNode.gain.value = 1; //Normalize sound output\n\n audioSource.connect(equalizerBands[0]);\n\n for (let i = 0; i < equalizerBands.length - 1; i++) {\n equalizerBands[i].connect(equalizerBands[i + 1]);\n }\n\n equalizerBands[equalizerBands.length - 1].connect(gainNode);\n gainNode.connect(this.audioCtx.destination);\n\n this.audioCtxStatus = 'ACTIVE';\n this.eqFilterBands = equalizerBands;\n } catch (error) {\n this.audioCtxStatus = 'FAILED';\n }\n }\n\n setPreset(id: keyof Preset) {\n const preset = presets.find((el) => el.id === id);\n console.log({ preset });\n if (\n !this.eqFilterBands ||\n this.eqFilterBands.length !== preset?.gains.length\n ) {\n console.error('Invalid data provided.');\n return;\n }\n for (let i = 0; i < this.eqFilterBands.length; i++) {\n this.eqFilterBands[i].gain.value = preset?.gains[i];\n }\n }\n\n static getPresets() {\n return presets;\n }\n\n status() {\n if (this.audioCtx.state === 'suspended') {\n this.audioCtx.resume();\n }\n return this.audioCtxStatus;\n }\n\n setCustomEQ(gains: number[]) {\n if (isValidArray(gains)) {\n this.eqFilterBands.forEach((band: BiquadFilterNode, index: number) => {\n band.gain.value = gains[index];\n });\n }\n }\n}\n\nexport { Equalizer };\n","import { PLAYBACK_STATE } from 'constants/common';\nimport ChangeNotifier from 'helpers/notifier';\nimport { HlsEventsCallbackMap } from 'types/audioEvents.types';\n\nexport const HLS_EVENTS_CALLBACK_MAP: HlsEventsCallbackMap = {\n ERROR: (e: Event, data: any) => {\n const type = data.type;\n const detail = data.details;\n const isFatal = data.fatal;\n console.log('STATUS', e.type);\n\n ChangeNotifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.ERROR,\n error: {\n type,\n isFatal,\n detail\n }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n FRAG_CHANGED: () => {\n console.log('FRAG_CHANGED');\n }\n};\n","import { AudioEvents } from 'types';\n\nexport const AUDIO_EVENTS: AudioEvents = Object.freeze({\n ABORT: 'abort',\n TIME_UPDATE: 'timeupdate',\n CAN_PLAY: 'canplay',\n CAN_PLAY_THROUGH: 'canplaythrough',\n DURATION_CHANGE: 'durationchange',\n ENDED: 'ended',\n EMPTIED: 'emptied',\n PLAYING: 'playing',\n WAITING: 'waiting',\n SEEKING: 'seeking',\n SEEKED: 'seeked',\n LOADED_META_DATA: 'loadedmetadata',\n LOADED_DATA: 'loadeddata',\n PLAY: 'play',\n PAUSE: 'pause',\n RATE_CHANGE: 'ratechange',\n VOLUME_CHANGE: 'volumechange',\n SUSPEND: 'suspend',\n STALLED: 'stalled',\n PROGRESS: 'progress',\n LOAD_START: 'loadstart',\n ERROR: 'error',\n TRACK_CHANGE: 'trackchange' // this is a custom event added to support track change\n});\n\nexport const HLS_EVENTS = {\n MEDIA_ATTACHING: 'hlsMediaAttaching',\n MEDIA_ATTACHED: 'hlsMediaAttached',\n MEDIA_DETACHING: 'hlsMediaDetaching',\n MEDIA_DETACHED: 'hlsMediaDetached',\n BUFFER_RESET: 'hlsBufferReset',\n BUFFER_CODECS: 'hlsBufferCodecs',\n BUFFER_CREATED: 'hlsBufferCreated',\n BUFFER_APPENDING: 'hlsBufferAppending',\n BUFFER_APPENDED: 'hlsBufferAppended',\n BUFFER_EOS: 'hlsBufferEos',\n BUFFER_FLUSHING: 'hlsBufferFlushing',\n BUFFER_FLUSHED: 'hlsBufferFlushed',\n MANIFEST_LOADING: 'hlsManifestLoading',\n MANIFEST_LOADED: 'hlsManifestLoaded',\n MANIFEST_PARSED: 'hlsManifestParsed',\n LEVEL_SWITCHING: 'hlsLevelSwitching',\n LEVEL_SWITCHED: 'hlsLevelSwitched',\n LEVEL_LOADING: 'hlsLevelLoading',\n LEVEL_LOADED: 'hlsLevelLoaded',\n LEVEL_UPDATED: 'hlsLevelUpdated',\n LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',\n LEVELS_UPDATED: 'hlsLevelsUpdated',\n AUDIO_TRACKS_UPDATED: 'hlsAudioTracksUpdated',\n AUDIO_TRACK_SWITCHING: 'hlsAudioTrackSwitching',\n AUDIO_TRACK_SWITCHED: 'hlsAudioTrackSwitched',\n AUDIO_TRACK_LOADING: 'hlsAudioTrackLoading',\n AUDIO_TRACK_LOADED: 'hlsAudioTrackLoaded',\n SUBTITLE_TRACKS_UPDATED: 'hlsSubtitleTracksUpdated',\n SUBTITLE_TRACKS_CLEARED: 'hlsSubtitleTracksCleared',\n SUBTITLE_TRACK_SWITCH: 'hlsSubtitleTrackSwitch',\n SUBTITLE_TRACK_LOADING: 'hlsSubtitleTrackLoading',\n SUBTITLE_TRACK_LOADED: 'hlsSubtitleTrackLoaded',\n SUBTITLE_FRAG_PROCESSED: 'hlsSubtitleFragProcessed',\n CUES_PARSED: 'hlsCuesParsed',\n NON_NATIVE_TEXT_TRACKS_FOUND: 'hlsNonNativeTextTracksFound',\n INIT_PTS_FOUND: 'hlsInitPtsFound',\n FRAG_LOADING: 'hlsFragLoading',\n FRAG_LOAD_EMERGENCY_ABORTED: 'hlsFragLoadEmergencyAborted',\n FRAG_LOADED: 'hlsFragLoaded',\n FRAG_DECRYPTED: 'hlsFragDecrypted',\n FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',\n FRAG_PARSING_USERDATA: 'hlsFragParsingUserdata',\n FRAG_PARSING_METADATA: 'hlsFragParsingMetadata',\n FRAG_PARSED: 'hlsFragParsed',\n FRAG_BUFFERED: 'hlsFragBuffered',\n FRAG_CHANGED: 'hlsFragChanged',\n FPS_DROP: 'hlsFpsDrop',\n FPS_DROP_LEVEL_CAPPING: 'hlsFpsDropLevelCapping',\n ERROR: 'hlsError',\n DESTROYING: 'hlsDestroying',\n KEY_LOADING: 'hlsKeyLoading',\n KEY_LOADED: 'hlsKeyLoaded',\n LIVE_BACK_BUFFER_REACHED: 'hlsLiveBackBufferReached',\n BACK_BUFFER_REACHED: 'hlsBackBufferReached'\n};\n\nexport const CUSTOM_AUDIO_EVENTS = Object.freeze({\n AUDIO_X_STATE: 'AUDIO_X_STATE'\n});\n","import HlsAdapter from 'adapters/hls';\nimport { AudioX } from 'audio';\nimport { isValidArray } from 'helpers/common';\nimport ChangeNotifier from 'helpers/notifier';\nimport {\n AudioEvents,\n EventListenerCallbackMap,\n EventListenersList,\n HlsEvents,\n HlsEventsCallbackMap\n} from 'types/audioEvents.types';\nimport { HlsListeners } from '../types/hls.js.js';\nimport { AUDIO_EVENTS, HLS_EVENTS } from './audioEvents';\n\n/**\n * this attaches event listeners, for audio also sends a flag to calculate playLog\n * loops through the event listeners map and attaches it to the audio element\n */\nconst attachDefaultEventListeners = (\n eventListenersCallbackMap: EventListenerCallbackMap,\n playLogEnabled: boolean = false\n) => {\n const audioInstance = AudioX.getAudioInstance();\n isValidArray(Object.keys(eventListenersCallbackMap)) &&\n Object.keys(eventListenersCallbackMap).forEach((evt) => {\n let event = evt as keyof AudioEvents;\n audioInstance?.addEventListener(AUDIO_EVENTS[event], (e: Event) => {\n if (evt && eventListenersCallbackMap[event]) {\n const listenerCallback = eventListenersCallbackMap[event];\n if (typeof listenerCallback === 'function') {\n listenerCallback(e, audioInstance, playLogEnabled);\n }\n }\n });\n });\n};\n\nconst attachCustomEventListeners = (\n eventListenersList: EventListenersList,\n enablePlayLog: boolean = false\n) => {\n const audioInstance = AudioX.getAudioInstance();\n if (isValidArray(eventListenersList)) {\n eventListenersList.forEach((evt) => {\n let event = evt as keyof AudioEvents;\n if (Object.keys(AUDIO_EVENTS).includes(event)) {\n audioInstance?.addEventListener(AUDIO_EVENTS[event], (e: Event) => {\n ChangeNotifier.notify(AUDIO_EVENTS[event], {\n e,\n audioInstance,\n enablePlayLog\n });\n });\n }\n });\n }\n};\n\nconst attachHlsEventsListeners = (\n hlsEventlistenerCallbackMap: HlsEventsCallbackMap,\n playLogEnabled: boolean = false\n) => {\n const hls = new HlsAdapter();\n const hlsInstance = hls.getHlsInstance();\n isValidArray(Object.keys(hlsEventlistenerCallbackMap)) &&\n Object.keys(hlsEventlistenerCallbackMap).forEach((evt) => {\n let event = evt as keyof HlsEvents;\n hlsInstance.on(\n HLS_EVENTS[event] as keyof HlsListeners,\n (e: any, data: any) => {\n if (event && hlsEventlistenerCallbackMap[event]) {\n const listenerCallback = hlsEventlistenerCallbackMap[event];\n if (typeof listenerCallback === 'function') {\n listenerCallback(e, data, hlsInstance, playLogEnabled);\n }\n }\n }\n );\n });\n};\n\nexport {\n attachCustomEventListeners,\n attachDefaultEventListeners,\n attachHlsEventsListeners\n};\n","declare global {\n interface Window {\n Hls: any;\n }\n}\n\nimport { AudioX } from 'audio';\nimport { URLS } from 'constants/common';\nimport { HLS_EVENTS_CALLBACK_MAP } from 'events/hlsEvents';\nimport { attachHlsEventsListeners } from 'events/listeners';\nimport { loadScript } from 'helpers/common';\nimport { MediaTrack } from 'types';\nimport type Hls from 'types/hls.js.js';\nimport type { HlsConfig } from 'types/hls.js.js';\n\nlet hlsInstance: Hls;\n\nclass HlsAdapter {\n private static _instance: HlsAdapter;\n private HlsClass: typeof Hls;\n\n constructor() {\n if (HlsAdapter._instance) {\n console.warn(\n 'Instantiation failed: cannot create multiple instance of HLS returning existing instance'\n );\n return HlsAdapter._instance;\n }\n HlsAdapter._instance = this;\n }\n\n async load() {\n await loadScript(\n URLS.HLS,\n () => {\n console.log('HLS Loaded');\n },\n 'hls'\n )\n .then(() => {\n this.HlsClass = window.Hls;\n window.Hls = undefined;\n })\n .catch((msg: string) => {\n console.log(msg);\n });\n\n return this.HlsClass;\n }\n\n async init(config: HlsConfig | {} = {}, enablePlayLog: boolean) {\n const Hls = await this.load();\n if (Hls.isSupported()) {\n hlsInstance = new Hls(config);\n attachHlsEventsListeners(HLS_EVENTS_CALLBACK_MAP, enablePlayLog);\n }\n }\n\n addHlsMedia(mediaTrack: MediaTrack) {\n const Hls = this.HlsClass;\n const audioInstance = AudioX.getAudioInstance();\n hlsInstance.attachMedia(audioInstance);\n hlsInstance.on(Hls.Events.MEDIA_ATTACHED, function () {\n hlsInstance.loadSource(mediaTrack.source);\n console.log('hls media attached');\n });\n }\n\n getHlsInstance() {\n return hlsInstance;\n }\n}\n\nexport default HlsAdapter;\n","import { ErrorEvents } from 'types/errorEvents.types';\n\nexport const ERROR_EVENTS: ErrorEvents = Object.freeze({\n 1: 'MEDIA_ERR_ABORTED',\n 3: 'MEDIA_ERR_DECODE',\n 2: 'MEDIA_ERR_NETWORK',\n 4: 'MEDIA_ERR_SRC_NOT_SUPPORTED',\n});\n","import { PLAYBACK_STATE } from 'constants/common';\nimport {\n calculateActualPlayedLength,\n getReadableErrorMessage\n} from 'helpers/common';\nimport ChangeNotifier from 'helpers/notifier';\nimport { AudioState, EventListenerCallbackMap } from 'types';\nimport { ERROR_EVENTS } from './errorEvents';\nconst notifier = ChangeNotifier;\n\nconst BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = {\n LOADED_META_DATA: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.BUFFERING,\n duration: audioInstance?.duration,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_state_${e.type}`\n );\n },\n\n CAN_PLAY: (e: Event) => {\n console.log('STATUS', e.type);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.BUFFERING,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n CAN_PLAY_THROUGH: (e: Event) => {\n console.log('STATUS', e.type);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.READY,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n PLAY: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.PLAYING,\n progress: audioInstance?.currentTime,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n PAUSE: (e: Event, audioInstance: HTMLAudioElement, playLogEnabled) => {\n console.log('STATUS', e.type);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.PAUSED,\n progress: audioInstance?.currentTime,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n if (playLogEnabled) {\n calculateActualPlayedLength(audioInstance, 'PAUSE');\n }\n },\n\n ENDED: (e: Event, audioInstance: HTMLAudioElement, playLogEnabled) => {\n console.log('STATUS', e.type);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.ENDED,\n progress: audioInstance?.currentTime,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n if (playLogEnabled) {\n calculateActualPlayedLength(audioInstance, 'ENDED');\n }\n },\n\n ERROR: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const errorCode = audioInstance.error?.code as keyof typeof ERROR_EVENTS;\n const message = getReadableErrorMessage(audioInstance);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.ERROR,\n error: {\n code: errorCode,\n message: ERROR_EVENTS[errorCode],\n readable: message\n }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n TIME_UPDATE: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const audioState = ChangeNotifier.getLatestState(\n 'AUDIO_X_STATE'\n ) as AudioState;\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: audioInstance.paused\n ? audioState.playbackState\n : PLAYBACK_STATE.PLAYING,\n progress: audioInstance?.currentTime,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n WAITING: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.BUFFERING,\n progress: audioInstance?.currentTime,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n VOLUME_CHANGE: (e: Event) => {\n console.log('STATUS', e.type);\n notifier.notify('AUDIO_STATE', {}, `audiox_baseEvents_state`);\n }\n};\n\nexport { BASE_EVENT_CALLBACK_MAP };\n","import { AudioX } from 'audio';\nimport { metaDataCreator } from 'helpers/common';\nimport ChangeNotifier from 'helpers/notifier';\nimport { AudioState } from 'types';\n\nexport const updateMetaData = (data: any) => {\n if ('mediaSession' in navigator) {\n navigator.mediaSession.metadata = new MediaMetadata(metaDataCreator(data));\n }\n};\n\nexport const attachMediaSessionHandlers = () => {\n if ('mediaSession' in navigator) {\n navigator.mediaSession.setActionHandler('play', () => {\n const audioInstance = AudioX.getAudioInstance();\n\n audioInstance.play();\n });\n navigator.mediaSession.setActionHandler('pause', () => {\n const audioInstance = AudioX.getAudioInstance();\n audioInstance.pause();\n });\n }\n};\n\nexport const updatePositionState = () => {\n ChangeNotifier.listen('AUDIO_X_STATE', (data: AudioState) => {\n if (data?.duration && data?.playbackRate && data?.progress) {\n navigator.mediaSession.setPositionState({\n duration: data.duration,\n playbackRate: data.playbackRate,\n position: data.progress\n });\n }\n });\n};\n","import { PLAYBACK_STATE } from 'constants/common';\nimport ChangeNotifier from 'helpers/notifier';\nimport { ReadyState } from 'types';\nimport { AudioState, MediaTrack } from 'types/audio.types';\n\nexport const READY_STATE: ReadyState = {\n HAVE_NOTHING: 0,\n HAVE_METADATA: 1,\n HAVE_CURRENT_DATA: 2,\n HAVE_FUTURE_DATA: 3,\n HAVE_ENOUGH_DATA: 4\n};\n\nexport const AUDIO_STATE: AudioState = {\n playbackState: PLAYBACK_STATE.IDLE,\n duration: 0,\n bufferedDuration: 0,\n progress: 0,\n volume: 50,\n playbackRate: 1,\n error: {\n code: null,\n message: '',\n readable: ''\n },\n currentTrack: {} as MediaTrack,\n currentTrackPlayTime: 0,\n previousTrackPlayTime: 0\n};\n\n/* Listen to state changes and update global audio state that is being exposed to outer world\n Do not subscribe to this event, this may cause unexpected behavior instead attach your own custom\n event listener, if you wish to have granular control on audio state. See: attachCustomEventListener \n*/\nChangeNotifier.listen(\n 'AUDIO_STATE',\n (data: AudioState) => {\n ChangeNotifier.notify('AUDIO_X_STATE', { ...AUDIO_STATE, ...data });\n },\n AUDIO_STATE\n);\n","import { Equalizer } from 'adapters/equalizer';\nimport HlsAdapter from 'adapters/hls';\nimport { AUDIO_X_CONSTANTS, PLAYBACK_STATE } from 'constants/common';\nimport { BASE_EVENT_CALLBACK_MAP } from 'events/baseEvents';\nimport {\n attachCustomEventListeners,\n attachDefaultEventListeners\n} from 'events/listeners';\nimport { calculateActualPlayedLength } from 'helpers/common';\nimport ChangeNotifier from 'helpers/notifier';\n\nimport {\n attachMediaSessionHandlers,\n updateMetaData\n} from 'mediasession/mediasessionHandler';\nimport { READY_STATE } from 'states/audioState';\nimport { EventListenersList } from 'types';\nimport { AudioInit, MediaTrack, PlaybackRate } from 'types/audio.types';\nimport { EqualizerStatus, Preset } from 'types/equalizer.types';\n\nlet audioInstance: HTMLAudioElement;\nconst notifier = ChangeNotifier;\n\nclass AudioX {\n private _audio: HTMLAudioElement;\n private isPlayLogEnabled: Boolean;\n private static _instance: AudioX;\n private eqStatus: EqualizerStatus = 'IDEAL';\n private isEqEnabled: boolean = false;\n private eqInstance: Equalizer;\n\n constructor() {\n if (AudioX._instance) {\n console.warn(\n 'Instantiation failed: cannot create multiple instance of AudioX returning existing instance'\n );\n return AudioX._instance;\n }\n if (\n process.env.NODE_ENV !== AUDIO_X_CONSTANTS?.DEVELOPMENT &&\n audioInstance\n ) {\n throw new Error('Cannot create multiple audio instance');\n }\n\n AudioX._instance = this;\n this._audio = new Audio();\n audioInstance = this._audio;\n }\n\n /**\n *\n * @param initProps initial config to initialize AudioX\n * @param initProps.mediaTrack mediaTrack Object containing metadata and source of the media\n * @param initProps.mediaTrack.title title of the Audio\n * @param initProps.mediaTrack.source URI of the Audio\n * @param initProps.mediaTrack.artwork artwork of the Audio\n * @param initProps.mediaTrack.duration duration of the audio\n * @param initProps.mediaTrack.genre genre of the audio\n * @param initProps.mediaTrack.album album of the audio\n * @param initProps.mediaTrack.comment comment for the audio\n * @param initProps.mediaTrack.year release year of the audio\n * @param initProps.mediaTrack.artist artist of the audio\n * @param mode mode of operation for AudioX\n * @param autoplay flag for autoplay\n * @param preloadStrategy strategy for preloading audio\n * @param playbackRate default playbackRate of the audio\n * @param attachAudioEventListeners flag for registering audio events\n * @param attachMediaSessionHandlers flag for registering mediaSession handlers\n */\n\n async init(initProps: AudioInit) {\n const {\n preloadStrategy = 'auto',\n autoPlay = false,\n useDefaultEventListeners = true,\n customEventListeners = null,\n showNotificationActions = false,\n enablePlayLog = false,\n enableHls = false,\n enableEQ = false,\n crossOrigin = 'anonymous',\n hlsConfig = {}\n } = initProps;\n\n this._audio?.setAttribute('id', 'audio_x_instance');\n this._audio.preload = preloadStrategy;\n this._audio.autoplay = autoPlay;\n this._audio.crossOrigin = crossOrigin;\n this.isPlayLogEnabled = enablePlayLog;\n\n if (useDefaultEventListeners || customEventListeners == null) {\n attachDefaultEventListeners(BASE_EVENT_CALLBACK_MAP, enablePlayLog);\n }\n\n if (showNotificationActions) {\n attachMediaSessionHandlers();\n }\n\n if (enableEQ) {\n this.isEqEnabled = enableEQ;\n }\n\n if (enableHls) {\n const hls = new HlsAdapter();\n hls.init(hlsConfig, enablePlayLog);\n }\n }\n\n async addMedia(mediaTrack: MediaTrack) {\n if (!mediaTrack) {\n return;\n }\n\n const mediaType = mediaTrack.source.includes('.m3u8') ? 'HLS' : 'DEFAULT';\n\n if (this.isPlayLogEnabled) {\n calculateActualPlayedLength(audioInstance, 'TRACK_CHANGE');\n }\n\n if (mediaType === 'HLS') {\n const hls = new HlsAdapter();\n const hlsInstance = hls.getHlsInstance();\n if (hlsInstance) {\n hlsInstance.detachMedia();\n hls.addHlsMedia(mediaTrack);\n } else {\n console.warn(\n 'The source provided seems to be a HLS stream but, hls playback is not enabled. Please have a look at init method of AudioX'\n );\n await this.reset();\n }\n } else {\n audioInstance.src = mediaTrack.source;\n }\n\n notifier.notify('AUDIO_STATE', {\n playbackState: PLAYBACK_STATE.TRACK_CHANGE,\n currentTrackPlayTime: 0,\n currentTrack: mediaTrack\n });\n\n updateMetaData(mediaTrack);\n audioInstance.load();\n }\n\n attachEq() {\n if (this.isEqEnabled && this.eqStatus === 'IDEAL') {\n try {\n const eq = new Equalizer();\n this.eqStatus = eq.status();\n this.eqInstance = eq;\n } catch (e) {\n console.log('failed to enable equalizer');\n }\n }\n }\n\n async play() {\n const isSourceAvailable = audioInstance.src !== '';\n if (\n audioInstance?.paused &&\n audioInstance.HAVE_ENOUGH_DATA === READY_STATE.HAVE_ENOUGH_DATA &&\n isSourceAvailable\n ) {\n await audioInstance\n .play()\n .then(() => {\n console.log('PLAYING');\n })\n .catch(() => {\n console.warn('cancelling current audio playback, track changed');\n });\n }\n }\n\n /**\n *\n * @param mediaTrack MediaTrack to be added and played\n *\n * Note: Use this method when you want to add media and do playback or want continuous playback\n * You can also call addMedia and Play Separately to achieve playback.\n */\n\n async addMediaAndPlay(mediaTrack: MediaTrack) {\n try {\n if (mediaTrack) {\n this.addMedia(mediaTrack).then(() => {\n if (audioInstance.HAVE_ENOUGH_DATA === READY_STATE.HAVE_ENOUGH_DATA) {\n setTimeout(async () => {\n this.attachEq();\n await this.play();\n }, 950);\n }\n });\n }\n } catch (error) {\n console.log('PLAYBACK FAILED');\n }\n }\n\n pause() {\n if (audioInstance && !audioInstance?.paused) {\n audioInstance?.pause();\n }\n }\n\n stop() {\n if (audioInstance && !audioInstance.paused) {\n audioInstance?.pause();\n audioInstance.currentTime = 0;\n }\n }\n\n /**\n * @method reset : This stops the playback and resets all the state of the audio\n */\n async reset() {\n if (audioInstance) {\n this.stop();\n audioInstance.src = '';\n audioInstance.srcObject = null;\n }\n }\n\n /**\n * @param volume : numeric value between 1-100 to be used.\n */\n setVolume(volume: number) {\n const actualVolume = volume / 100;\n if (audioInstance) {\n audioInstance.volume = actualVolume;\n notifier.notify('AUDIO_STATE', {\n volume: volume\n });\n }\n }\n /**\n * @param playbackRate : a number denoting speed at which the playback should happen,\n */\n setPlaybackRate(playbackRate: PlaybackRate) {\n if (audioInstance) {\n audioInstance.playbackRate = playbackRate;\n notifier.notify('AUDIO_STATE', {\n playbackRate\n });\n }\n }\n\n mute() {\n if (audioInstance && !audioInstance.muted) {\n audioInstance.muted = true;\n }\n }\n\n seek(time: number) {\n if (audioInstance) {\n audioInstance.currentTime = time;\n }\n }\n\n async destroy() {\n if (audioInstance) {\n await this.reset();\n audioInstance.removeAttribute('src');\n audioInstance.load();\n }\n }\n\n subscribe(eventName: string, callback: (data: any) => void, state: any = {}) {\n const unsubscribe = notifier.listen(eventName, callback, state);\n return unsubscribe;\n }\n\n attachEventListeners(eventListenersList: EventListenersList) {\n attachCustomEventListeners(eventListenersList);\n }\n\n getPresets() {\n return Equalizer.getPresets();\n }\n\n setPreset(id: keyof Preset) {\n this.eqInstance.setPreset(id);\n }\n\n setCustomEQ(gains: number[]) {\n this.eqInstance.setCustomEQ(gains);\n }\n\n get id() {\n return audioInstance?.getAttribute('id');\n }\n\n static getAudioInstance() {\n return audioInstance;\n }\n}\n\nexport { AudioX };\n"]} \ No newline at end of file