From 40b36c4d852b141143be285f5268dff0b61f12fe Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Fri, 21 Jun 2024 21:48:26 +0530 Subject: [PATCH 1/5] mediaSession next and previous handler and queue updates --- src/audio.ts | 24 ++++++++++++++++++++++ src/helpers/common.ts | 2 +- src/mediasession/mediasessionHandler.ts | 27 ++++++++++++++++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/audio.ts b/src/audio.ts index f186eb6..d5f114f 100644 --- a/src/audio.ts +++ b/src/audio.ts @@ -38,6 +38,7 @@ class AudioX { private eqStatus: EqualizerStatus = 'IDEAL'; private isEqEnabled: boolean = false; private eqInstance: Equalizer; + private showNotificationsActions: boolean = false; constructor() { if (AudioX._instance) { @@ -112,6 +113,7 @@ class AudioX { } if (showNotificationActions) { + this.showNotificationsActions = true; attachMediaSessionHandlers(); } @@ -211,6 +213,7 @@ class AudioX { this._fetchFn = fetchFn; await fetchFn(currentTrack as MediaTrack); } + if (this._queue && isValidArray(this._queue)) { this._currentQueueIndex = this._queue.findIndex( (track) => track.id === currentTrack?.id @@ -294,6 +297,13 @@ class AudioX { } } + seekBy(time: number) { + if (audioInstance && audioInstance.currentTime) { + const currentProgress = audioInstance.currentTime; + audioInstance.currentTime = currentProgress + time; + } + } + async destroy() { if (audioInstance) { await this.reset(); @@ -343,6 +353,10 @@ class AudioX { break; } handleQueuePlayback(); + // Attaching MediaSession Handler again as this will make sure the next and previous button show up in notification + if (this.showNotificationsActions) { + attachMediaSessionHandlers(); + } } playNext() { @@ -371,6 +385,16 @@ class AudioX { } } + addToQueue(mediaTracks: MediaTrack | MediaTrack[]) { + if (this._queue && isValidArray(this._queue)) { + if (Array.isArray(mediaTracks)) { + this._queue = [...this._queue, ...mediaTracks]; + } else { + this._queue.push(mediaTracks); + } + } + } + removeFromQueue(mediaTrack: MediaTrack) { if (this._queue && isValidArray(this._queue)) { const queue = this._queue.filter( diff --git a/src/helpers/common.ts b/src/helpers/common.ts index fe2f257..46f6bf4 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -120,11 +120,11 @@ const loadScript = ( const handleQueuePlayback = () => { const audio = new AudioX(); - const queue = audio.getQueue(); let hasEnded = false; const audioStateListener = (state: AudioState) => { if (state.playbackState === 'ended' && !hasEnded) { + const queue = audio.getQueue(); hasEnded = true; if (queue && isValidArray(queue)) { audio.playNext(); diff --git a/src/mediasession/mediasessionHandler.ts b/src/mediasession/mediasessionHandler.ts index 72edccb..db7681e 100644 --- a/src/mediasession/mediasessionHandler.ts +++ b/src/mediasession/mediasessionHandler.ts @@ -10,25 +10,42 @@ export const updateMetaData = (data: any) => { }; export const attachMediaSessionHandlers = () => { + const audio = new AudioX(); if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('play', () => { const audioInstance = AudioX.getAudioInstance(); audioInstance.play(); }); + navigator.mediaSession.setActionHandler('pause', () => { const audioInstance = AudioX.getAudioInstance(); audioInstance.pause(); }); + + // Only add next and previous handler if there is a valid queue + if (audio.getQueue().length) { + navigator.mediaSession.setActionHandler('previoustrack', () => { + audio.playPrevious(); + }); + + navigator.mediaSession.setActionHandler('nexttrack', () => { + audio.playNext(); + }); + } } }; export const updatePositionState = () => { - ChangeNotifier.listen('AUDIO_X_STATE', (data: AudioState) => { - if (data?.duration && data?.playbackRate && data?.progress) { + ChangeNotifier.listen('AUDIO_X_STATE', (audioState: AudioState) => { + if ( + audioState?.duration && + audioState?.playbackRate && + audioState?.progress + ) { navigator.mediaSession.setPositionState({ - duration: data.duration, - playbackRate: data.playbackRate, - position: data.progress + duration: audioState.duration, + playbackRate: audioState.playbackRate, + position: audioState.progress }); } }); From 01bdc7a11a95c8b6aed718626ca2745d1857fc7b Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Fri, 21 Jun 2024 21:55:20 +0530 Subject: [PATCH 2/5] update README --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 97d746b..fbaf41f 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,9 @@ For a comprehensive list of formats support visit [MDN audio codec guide](https: - Casting support - Dash media playback - DRM -- ~~Equalizer~~ [✓] Done -- Updates to APIs for better DX -- React hooks to easily get started with React. - Ads Support +- ~~Equalizer~~ [✓] Done +- ~~Updates to APIs for better DX~~ [✓] Done - ~~Queue Support~~ [✓] Done. ### Installation @@ -104,8 +103,8 @@ audio.play(); audio.pause(); // Get the Audio State -audio.subscribe("AUDIO_X_STATE", (data: AudioState) => { - console.log(data); +audio.subscribe("AUDIO_X_STATE", (audioState: AudioState) => { + console.log(audioState); }); // Sample Audio State @@ -270,6 +269,10 @@ audio.addMediaAndPlay(null, async (currentTrack: MediaTrack) => { // To add a single track to queue audio.addToQueue(track); + +// To add a multiple tracks to queue + +audio.addToQueue([track1, track2, track3]); ``` ```JS @@ -290,6 +293,18 @@ audio.playNext(); audio.playPrevious(); ``` +```JS +// To seek to a particular position + +audio.seek(position); // position is basically time in seconds +``` + +```JS +// To seek by to a particular time range + +audio.seekBy(time); // time range in seconds to seek +``` + ### Author --- From a521342ce5dd4105e87d767ec79b15ab67302c9f Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Fri, 21 Jun 2024 22:35:06 +0530 Subject: [PATCH 3/5] minor behaviour change in support of audio_x for seeking (retain state while seek) --- src/events/baseEvents.ts | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/events/baseEvents.ts b/src/events/baseEvents.ts index c20506a..1901b9b 100644 --- a/src/events/baseEvents.ts +++ b/src/events/baseEvents.ts @@ -68,28 +68,35 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { CAN_PLAY: (e: Event) => { console.log('STATUS', e.type); + const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; notifier.notify( 'AUDIO_STATE', { - playbackState: PLAYBACK_STATE.READY, + playbackState: + audioState.playbackState === 'paused' + ? PLAYBACK_STATE.PAUSED + : PLAYBACK_STATE.READY, error: { code: null, message: '', readable: '' } - }, + } as AudioState, `audiox_baseEvents_state_${e.type}` ); }, - CAN_PLAY_THROUGH: (e: Event) => { + CAN_PLAY_THROUGH: (e: Event, audioInstance: HTMLAudioElement) => { const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; + const isPaused = audioInstance.paused; console.log('STATUS', e.type); + // below we check if the audio was already in paused state then we keep it as paused instead going to ready this make sure ready is fired only on the first load. notifier.notify( 'AUDIO_STATE', { - playbackState: - audioState.playbackState === 'playing' - ? PLAYBACK_STATE.PLAYING // fix for live streams as canplaythrough event is can be behave weirdly as there is no known end to the media - : PLAYBACK_STATE.READY, + playbackState: isPaused + ? PLAYBACK_STATE.PAUSED + : audioState.playbackState === 'playing' + ? PLAYBACK_STATE.PLAYING // fix for live streams as canplaythrough event is can be behave weirdly as there is no known end to the media + : PLAYBACK_STATE.READY, error: { code: null, message: '', readable: '' } }, `audiox_baseEvents_state_${e.type}` @@ -205,6 +212,22 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { VOLUME_CHANGE: (e: Event) => { console.log('STATUS', e.type); notifier.notify('AUDIO_STATE', {}, `audiox_baseEvents_state`); + }, + + SEEKED: (e, audioInstance) => { + const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; + notifier.notify( + 'AUDIO_STATE', + { + playbackState: + audioState.playbackState === 'paused' + ? 'paused' + : audioState.playbackState, + progress: audioInstance?.currentTime, + error: { code: null, message: '', readable: '' } + } as AudioState, + `audiox_baseEvents_state_${e.type}` + ); } }; From 67b8e38a53f38583ad177ad1f9b585ac1558c1b7 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Fri, 21 Jun 2024 23:01:31 +0530 Subject: [PATCH 4/5] bufferedDuration is now fixed --- src/events/baseEvents.ts | 46 +++++++++++++++++++++++++++++----------- src/helpers/common.ts | 12 +++++++++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/events/baseEvents.ts b/src/events/baseEvents.ts index 1901b9b..2b34acf 100644 --- a/src/events/baseEvents.ts +++ b/src/events/baseEvents.ts @@ -1,6 +1,7 @@ import { PLAYBACK_STATE } from 'constants/common'; import { calculateActualPlayedLength, + getBufferedDuration, getReadableErrorMessage } from 'helpers/common'; import ChangeNotifier from 'helpers/notifier'; @@ -12,20 +13,25 @@ const notifier = ChangeNotifier; const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { LOAD_START: (e, audioInstance: HTMLAudioElement) => { console.log('STATUS', e.type); + const bufferedDuration = getBufferedDuration(audioInstance); + notifier.notify( 'AUDIO_STATE', { playbackState: PLAYBACK_STATE.BUFFERING, duration: audioInstance?.duration, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration }, `audiox_baseEvents_state_${e.type}` ); }, DURATION_CHANGE: (e, audioInstance: HTMLAudioElement) => { - const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; console.log('STATUS', e.type); + const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; + const bufferedDuration = getBufferedDuration(audioInstance); + notifier.notify( 'AUDIO_STATE', { @@ -34,7 +40,8 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { ? PLAYBACK_STATE.PLAYING // fix for live streams where duration change is fired even when audio is playing : PLAYBACK_STATE.DURATION_CHANGE, duration: audioInstance?.duration, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration }, `audiox_baseEvents_state_${e.type}` ); @@ -42,12 +49,15 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { LOADED_META_DATA: (e: Event, audioInstance: HTMLAudioElement) => { console.log('STATUS', e.type); + const bufferedDuration = getBufferedDuration(audioInstance); + notifier.notify( 'AUDIO_STATE', { playbackState: PLAYBACK_STATE.BUFFERING, duration: audioInstance?.duration, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration }, `audiox_baseEvents_state_${e.type}` ); @@ -55,20 +65,23 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { LOADED_DATA: (e, audioInstance: HTMLAudioElement) => { console.log('STATUS', e.type); + const bufferedDuration = getBufferedDuration(audioInstance); notifier.notify( 'AUDIO_STATE', { playbackState: PLAYBACK_STATE.BUFFERING, duration: audioInstance?.duration, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration }, `audiox_baseEvents_state_${e.type}` ); }, - CAN_PLAY: (e: Event) => { + CAN_PLAY: (e: Event, audioInstance: HTMLAudioElement) => { console.log('STATUS', e.type); const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; + const bufferedDuration = getBufferedDuration(audioInstance); notifier.notify( 'AUDIO_STATE', @@ -77,16 +90,19 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { audioState.playbackState === 'paused' ? PLAYBACK_STATE.PAUSED : PLAYBACK_STATE.READY, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration } as AudioState, `audiox_baseEvents_state_${e.type}` ); }, CAN_PLAY_THROUGH: (e: Event, audioInstance: HTMLAudioElement) => { + console.log('STATUS', e.type); + const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; const isPaused = audioInstance.paused; - console.log('STATUS', e.type); + const bufferedDuration = getBufferedDuration(audioInstance); // below we check if the audio was already in paused state then we keep it as paused instead going to ready this make sure ready is fired only on the first load. notifier.notify( @@ -97,7 +113,8 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { : audioState.playbackState === 'playing' ? PLAYBACK_STATE.PLAYING // fix for live streams as canplaythrough event is can be behave weirdly as there is no known end to the media : PLAYBACK_STATE.READY, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration }, `audiox_baseEvents_state_${e.type}` ); @@ -182,6 +199,7 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { TIME_UPDATE: (e: Event, audioInstance: HTMLAudioElement) => { console.log('STATUS', e.type); const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; + const bufferedDuration = getBufferedDuration(audioInstance); notifier.notify( 'AUDIO_STATE', @@ -190,7 +208,8 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { ? audioState?.playbackState : PLAYBACK_STATE.PLAYING, progress: audioInstance?.currentTime, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration }, `audiox_baseEvents_state_${e.type}` ); @@ -214,8 +233,10 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { notifier.notify('AUDIO_STATE', {}, `audiox_baseEvents_state`); }, - SEEKED: (e, audioInstance) => { + SEEKED: (e: any, audioInstance: HTMLAudioElement) => { const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState; + const bufferedDuration = getBufferedDuration(audioInstance); + notifier.notify( 'AUDIO_STATE', { @@ -224,7 +245,8 @@ const BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = { ? 'paused' : audioState.playbackState, progress: audioInstance?.currentTime, - error: { code: null, message: '', readable: '' } + error: { code: null, message: '', readable: '' }, + bufferedDuration } as AudioState, `audiox_baseEvents_state_${e.type}` ); diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 46f6bf4..8b3a187 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -138,6 +138,17 @@ const handleQueuePlayback = () => { ChangeNotifier.listen('AUDIO_STATE', audioStateListener); }; +const getBufferedDuration = (audioInstance: HTMLAudioElement) => { + const { buffered } = audioInstance; + let bufferedDuration = 0; + + for (let i = 0; i < buffered.length; i++) { + bufferedDuration += buffered.end(i) - buffered.start(i); + } + + return bufferedDuration; +}; + const shuffle = (array: T[]): T[] => { const shuffledArray = [...array]; @@ -151,6 +162,7 @@ const shuffle = (array: T[]): T[] => { }; export { + getBufferedDuration, getReadableErrorMessage, handleQueuePlayback, isValidArray, From 4d9cb7602013bbfe70acc08d12b1d3e158b074d2 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Fri, 21 Jun 2024 23:11:04 +0530 Subject: [PATCH 5/5] v1.0.9 --- dist/index.d.ts | 3 +++ dist/index.js | 4 ++-- dist/index.js.map | 2 +- package.json | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dist/index.d.ts b/dist/index.d.ts index 4974f3a..22e23e4 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -3353,6 +3353,7 @@ declare class AudioX { private eqStatus; private isEqEnabled; private eqInstance; + private showNotificationsActions; constructor(); init(initProps: AudioInit): Promise; addMedia(mediaTrack: MediaTrack): Promise; @@ -3366,6 +3367,7 @@ declare class AudioX { setPlaybackRate(playbackRate: PlaybackRate): void; mute(): void; seek(time: number): void; + seekBy(time: number): void; destroy(): Promise; subscribe(eventName: string, callback: (data: any) => void, state?: any): () => void; addEventListener(event: keyof HTMLMediaElementEventMap, callback: (data: any) => void): void; @@ -3381,6 +3383,7 @@ declare class AudioX { playNext(): void; playPrevious(): void; clearQueue(): void; + addToQueue(mediaTracks: MediaTrack | MediaTrack[]): void; removeFromQueue(mediaTrack: MediaTrack): void; getQueue(): MediaTrack[]; get id(): string | null; diff --git a/dist/index.js b/dist/index.js index b79b550..09af596 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,5 +1,5 @@ -var B=Object.defineProperty;var M=Object.getOwnPropertySymbols;var re=Object.prototype.hasOwnProperty,oe=Object.prototype.propertyIsEnumerable;var U=(s,e,t)=>e in s?B(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,m=(s,e)=>{for(var t in e||(e={}))re.call(e,t)&&U(s,t,e[t]);if(M)for(var t of M(e))oe.call(e,t)&&U(s,t,e[t]);return s};var n=(s,e)=>B(s,"name",{value:e,configurable:!0});var u=(s,e,t)=>(U(s,typeof e!="symbol"?e+"":e,t),t);var p=(s,e,t)=>new Promise((a,i)=>{var o=A=>{try{f(t.next(A));}catch(S){i(S);}},c=A=>{try{f(t.throw(A));}catch(S){i(S);}},f=A=>A.done?a(A.value):Promise.resolve(A.value).then(o,c);f((t=t.apply(s,e)).next());});var q=[{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}],I=[{name:"Default",id:"default",default:!0,gains:[0,0,0,0,0,0,0,0,0,0]},{name:"Club",id:"club",default:!0,gains:[0,0,4.8,3.36,3.36,3.36,1.92,0,0,0]},{name:"Live",id:"live",default:!0,gains:[-2.88,0,2.4,3.36,3.36,3.36,2.4,1.44,1.44,1.44]},{name:"Party",id:"Party",default:!0,gains:[4.32,4.32,0,0,0,0,0,0,4.32,4.32]},{name:"Pop",id:"pop",default:!0,gains:[.96,2.88,4.32,4.8,3.36,0,-1.44,-1.44,.96,.96]},{name:"Soft",id:"soft",default:!0,gains:[2.88,.96,0,-1.44,0,2.4,4.8,5.76,6.72,7.2]},{name:"Ska",id:"ska",default:!0,gains:[-1.44,-2.88,-2.4,0,2.4,3.36,5.28,5.76,6.72,5.76]},{name:"Reggae",id:"reggae",default:!0,gains:[0,0,0,-3.36,0,3.84,3.84,0,0,0]},{name:"Rock",id:"rock",default:!0,gains:[4.8,2.88,-3.36,-4.8,-1.92,2.4,5.28,6.72,6.72,6.72]},{name:"Dance",id:"dance",default:!0,gains:[5.76,4.32,1.44,0,0,-3.36,-4.32,-4.32,0,0]},{name:"Techno",id:"techno",default:!0,gains:[4.8,3.36,0,-3.36,-2.88,0,4.8,5.76,5.76,5.28]},{name:"Headphones",id:"headphones",default:!0,gains:[2.88,6.72,3.36,-1.92,-1.44,.96,2.88,5.76,7.68,8.64]},{name:"Soft rock",id:"soft_rock",default:!0,gains:[2.4,2.4,1.44,0,-2.4,-3.36,-1.92,0,1.44,5.28]},{name:"Classical",id:"classical",default:!0,gains:[0,0,0,0,0,0,-4.32,-4.32,-4.32,-5.76]},{name:"Large Hall",id:"large_hall",default:!0,gains:[6.24,6.24,3.36,3.36,0,-2.88,-2.88,-2.88,0,0]},{name:"Full Bass",id:"full_base",default:!0,gains:[4.8,5.76,5.76,3.36,.96,-2.4,-4.8,-6.24,-6.72,-6.72]},{name:"Full Treble",id:"full_treble",default:!0,gains:[-5.76,-5.76,-5.76,-2.4,1.44,6.72,9.6,9.6,9.6,10.08]},{name:"Laptop Speakers",id:"laptop_speakers",default:!0,gains:[2.88,6.72,3.36,-1.92,-1.44,.96,2.88,5.76,7.68,8.64]},{name:"Full Bass & Treble",id:"bass_treble",default:!0,gains:[4.32,3.36,0,-4.32,-2.88,.96,4.8,6.72,7.2,7.2]}];var P=Object.freeze({REACT:"REACT",VANILLA:"VANILLA",DEVELOPMENT:"development"}),l=Object.freeze({BUFFERING:"buffering",PLAYING:"playing",PAUSED:"paused",READY:"ready",IDLE:"idle",ENDED:"ended",STALLED:"stalled",ERROR:"error",TRACK_CHANGE:"trackchanged",DURATION_CHANGE:"durationchanged"}),R=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."}),V={HLS:"https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.11/hls.min.js",CAST:"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"};var d,ne=(d=class{static validateEventName(e){if(!e||typeof e!="string")throw new Error("Invalid event name")}static notify(e,t,a="audiox_notifier_default"){this.validateEventName(e);let i=d.listeners[e];i&&t!==null&&(d.notifierState[e]=m(m({},d.notifierState[e]||{}),t),i.forEach(o=>{o(d.notifierState[e]);}));}static listen(e,t,a={}){if(this.validateEventName(e),typeof t!="function")throw new Error("Callback must be a function");return d.listeners[e]?d.listeners[e].add(t):(d.notifierState[e]=a,d.listeners[e]=new Set([t])),()=>{let i=d.listeners[e];i&&(i.delete(t),i.size===0&&delete d.listeners[e]);}}static multiListen(e,t,a={}){if(this.validateEventName(e),!Array.isArray(t)||t.length===0)throw new Error("Callbacks must be a non-empty array of functions");let i=t.map(o=>d.listen(e,o,a));return ()=>{i.forEach(o=>o());}}static getLatestState(e){return this.validateEventName(e),d.notifierState[e]}},n(d,"ChangeNotifier"),u(d,"listeners",{}),u(d,"notifierState",{}),d),_=ne;var T=n(s=>s&&Array.isArray(s)&&s.length,"isValidArray"),Y=n(s=>s instanceof Function&&typeof s=="function","isValidFunction");var K={},X=n(s=>{let e="",t=s.error;switch(t==null?void 0:t.code){case MediaError.MEDIA_ERR_ABORTED:e+=R.MEDIA_ERR_ABORTED;break;case MediaError.MEDIA_ERR_NETWORK:e+=R.MEDIA_ERR_NETWORK;break;case MediaError.MEDIA_ERR_DECODE:e+=R.MEDIA_ERR_DECODE;break;case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:e+=R.MEDIA_ERR_SRC_NOT_SUPPORTED;break;default:e+=R.DEFAULT;break}return e},"getReadableErrorMessage"),Q=n(s=>{var S;let{title:e,album:t,artist:a,artwork:i}=s,o=i?(S=i[0])==null?void 0:S.src:"",f=["96x96","128x128","192x192","256x256","384x384","512x512"].map(b=>({src:o,sizes:b,type:"image/png"}));return {title:e,album:t,artist:a,artwork:f}},"metaDataCreator"),F=0,L=n((s,e)=>{let t=new Set;for(let o=0;oo+c,0);F=["ENDED","TRACK_CHANGE","PAUSE"].includes(e)?i:F,_.notify("AUDIO_STATE",{currentTrackPlayTime:i,previousTrackPlayTime:F});},"calculateActualPlayedLength"),j=n((s,e,t)=>new Promise((a,i)=>{if(window instanceof Window&&window.document)if(K[t])e(),a();else {K[t]=!0;let o=document.createElement("script");o.type="text/javascript",o.src=s,o.async=!0,o.onload=()=>{e(),a();},document.head.appendChild(o);}else i(`Window not ready unable to initialize ${t}`);}),"loadScript"),z=n(()=>{let s=new h,e=s.getQueue(),t=!1,a=n(i=>{i.playbackState==="ended"&&!t&&(t=!0,e&&T(e)&&s.playNext()),i.playbackState!=="ended"&&(t=!1);},"audioStateListener");_.listen("AUDIO_STATE",a);},"handleQueuePlayback"),$=n(s=>{let e=[...s];for(let t=e.length-1;t>0;t--){let a=Math.floor(Math.random()*t);[e[t],e[a]]=[e[a],e[t]];}return e},"shuffle");var g,k=(g=class{constructor(){u(this,"audioCtx");u(this,"audioCtxStatus");u(this,"eqFilterBands");if(g._instance)return g._instance;this.initializeAudioContext(),g._instance=this;}initializeAudioContext(){typeof AudioContext!="undefined"?this.audioCtx=new AudioContext:typeof window.webkitAudioContext!="undefined"&&(this.audioCtx=new window.webkitAudioContext),this.audioCtxStatus="ACTIVE",this.init(),this.audioCtx.state==="suspended"&&this.addResumeListener();}addResumeListener(){let e=n(()=>{this.audioCtx.resume(),setTimeout(()=>{this.audioCtx.state==="running"&&document.body.removeEventListener("click",e,!1);},0);},"resume");document.body.addEventListener("click",e,!1);}init(){try{let e=h.getAudioInstance(),t=this.audioCtx.createMediaElementSource(e),a=q.map(o=>{let c=this.audioCtx.createBiquadFilter();return c.type=o.type,c.frequency.value=o.frequency,c.gain.value=o.gain,c.Q.value=1,c}),i=this.audioCtx.createGain();i.gain.value=1,t.connect(a[0]);for(let o=0;oa.id===e);t&&(!this.eqFilterBands||this.eqFilterBands.length!==t.gains.length||this.eqFilterBands.forEach((a,i)=>{a.gain.value=t.gains[i];}));}static getPresets(){return I}status(){return this.audioCtx.state==="suspended"&&this.audioCtx.resume(),this.audioCtxStatus}setCustomEQ(e){T(e)&&this.eqFilterBands.forEach((t,a)=>{t.gain.value=e[a];});}},n(g,"Equalizer"),u(g,"_instance"),g);var W={ERROR:(s,e)=>{let t=e.type,a=e.details,i=e.fatal;_.notify("AUDIO_STATE",{playbackState:l.ERROR,error:{type:t,isFatal:i,detail:a}},`audiox_baseEvents_state_${s.type}`);},FRAG_CHANGED:()=>{}};var x=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"}),J={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 H=n((s,e=!1)=>{let t=h.getAudioInstance();T(Object.keys(s))&&Object.keys(s).forEach(a=>{let i=a;t==null||t.addEventListener(x[i],o=>{if(a&&s[i]){let c=s[i];typeof c=="function"&&c(o,t,e);}});});},"attachEventListeners");var Z=n((s,e=!1)=>{let a=new O().getHlsInstance();T(Object.keys(s))&&Object.keys(s).forEach(i=>{let o=i;a.on(J[o],(c,f)=>{if(o&&s[o]){let A=s[o];typeof A=="function"&&A(c,f,a,e);}});});},"attachHlsEventsListeners");var C,D,le=(D=class{constructor(){u(this,"HlsClass");if(D._instance)return D._instance;D._instance=this;}load(){return p(this,null,function*(){return yield j(V.HLS,()=>{},"hls").then(()=>{this.HlsClass=window.Hls,window.Hls=void 0;}).catch(e=>{}),this.HlsClass})}init(){return p(this,arguments,function*(e={},t){let a=yield this.load();a.isSupported()&&(C=new a(e),Z(W,t));})}addHlsMedia(e){let t=this.HlsClass,a=h.getAudioInstance();C.loadSource(e.source),C.attachMedia(a),C.on(t.Events.MEDIA_ATTACHED,function(){});}getHlsInstance(){return C}},n(D,"HlsAdapter"),u(D,"_instance"),D),O=le;var ee=Object.freeze({1:"MEDIA_ERR_ABORTED",3:"MEDIA_ERR_DECODE",2:"MEDIA_ERR_NETWORK",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"});var E=_,te={LOAD_START:(s,e)=>{E.notify("AUDIO_STATE",{playbackState:l.BUFFERING,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},DURATION_CHANGE:(s,e)=>{let t=E.getLatestState("AUDIO_X_STATE");E.notify("AUDIO_STATE",{playbackState:t.playbackState==="playing"?l.PLAYING:l.DURATION_CHANGE,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},LOADED_META_DATA:(s,e)=>{E.notify("AUDIO_STATE",{playbackState:l.BUFFERING,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},LOADED_DATA:(s,e)=>{E.notify("AUDIO_STATE",{playbackState:l.BUFFERING,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},CAN_PLAY:s=>{E.notify("AUDIO_STATE",{playbackState:l.READY,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},CAN_PLAY_THROUGH:s=>{let e=E.getLatestState("AUDIO_X_STATE");E.notify("AUDIO_STATE",{playbackState:e.playbackState==="playing"?l.PLAYING:l.READY,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},PLAY:(s,e)=>{E.notify("AUDIO_STATE",{playbackState:l.PLAYING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},PLAYING:(s,e)=>{E.notify("AUDIO_STATE",{playbackState:l.PLAYING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},PAUSE:(s,e,t)=>{E.notify("AUDIO_STATE",{playbackState:l.PAUSED,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`),t&&L(e,"PAUSE");},ENDED:(s,e,t)=>{E.notify("AUDIO_STATE",{playbackState:l.ENDED,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`),t&&L(e,"ENDED");},ERROR:(s,e)=>{var i;let t=(i=e.error)==null?void 0:i.code,a=X(e);E.notify("AUDIO_STATE",{playbackState:l.ERROR,error:{code:t,message:ee[t],readable:a}},`audiox_baseEvents_state_${s.type}`);},TIME_UPDATE:(s,e)=>{let t=E.getLatestState("AUDIO_X_STATE");E.notify("AUDIO_STATE",{playbackState:e.paused?t==null?void 0:t.playbackState:l.PLAYING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},WAITING:(s,e)=>{E.notify("AUDIO_STATE",{playbackState:l.BUFFERING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},VOLUME_CHANGE:s=>{E.notify("AUDIO_STATE",{},"audiox_baseEvents_state");}};var se=n(s=>{"mediaSession"in navigator&&(navigator.mediaSession.metadata=new MediaMetadata(Q(s)));},"updateMetaData"),ae=n(()=>{"mediaSession"in navigator&&(navigator.mediaSession.setActionHandler("play",()=>{h.getAudioInstance().play();}),navigator.mediaSession.setActionHandler("pause",()=>{h.getAudioInstance().pause();}));},"attachMediaSessionHandlers");var v={HAVE_NOTHING:0,HAVE_METADATA:1,HAVE_CURRENT_DATA:2,HAVE_FUTURE_DATA:3,HAVE_ENOUGH_DATA:4},w={playbackState:l.IDLE,duration:0,bufferedDuration:0,progress:0,volume:50,playbackRate:1,error:{code:null,message:"",readable:""},currentTrack:{},currentTrackPlayTime:0,previousTrackPlayTime:0};_.listen("AUDIO_STATE",s=>{_.notify("AUDIO_X_STATE",m(m({},w),s));},w);var r,N=_,y,h=(y=class{constructor(){u(this,"_audio");u(this,"isPlayLogEnabled");u(this,"_queue");u(this,"_currentQueueIndex",0);u(this,"_fetchFn");u(this,"eqStatus","IDEAL");u(this,"isEqEnabled",!1);u(this,"eqInstance");var e;if(y._instance)return y._instance;if(process.env.NODE_ENV!==((e=P)==null?void 0:e.DEVELOPMENT)&&r)throw new Error("Cannot create multiple audio instance");y._instance=this,this._audio=new Audio,r=this._audio;}init(e){return p(this,null,function*(){var G;let{preloadStrategy:t="auto",autoPlay:a=!1,useDefaultEventListeners:i=!0,customEventListeners:o=null,showNotificationActions:c=!1,enablePlayLog:f=!1,enableHls:A=!1,enableEQ:S=!1,crossOrigin:b="anonymous",hlsConfig:ie={}}=e;(G=this._audio)==null||G.setAttribute("id","audio_x_instance"),this._audio.preload=t,this._audio.autoplay=a,this._audio.crossOrigin=b,this.isPlayLogEnabled=f,o!==null?H(o,!1):H(te,f),c&&ae(),S&&(this.isEqEnabled=S),A&&new O().init(ie,f);})}addMedia(e){return p(this,null,function*(){if(!e)return;let t=e.source.includes(".m3u8")?"HLS":"DEFAULT";if(this.isPlayLogEnabled&&L(r,"TRACK_CHANGE"),t==="HLS"){let a=new O,i=a.getHlsInstance();i?(i.detachMedia(),a.addHlsMedia(e)):yield this.reset();}else r.src=e.source;N.notify("AUDIO_STATE",{playbackState:l.TRACK_CHANGE,currentTrackPlayTime:0,currentTrack:e}),se(e),r.load();})}attachEq(){if(this.isEqEnabled&&this.eqStatus==="IDEAL")try{let e=new k;this.eqStatus=e.status(),this.eqInstance=e;}catch(e){}}play(){return p(this,null,function*(){let e=r.src!=="";r!=null&&r.paused&&r.HAVE_ENOUGH_DATA===v.HAVE_ENOUGH_DATA&&e&&(yield r.play().then(()=>{}).catch(()=>{}));})}addMediaAndPlay(e,t){return p(this,null,function*(){let a=e||(this._queue.length>0?this._queue[0]:void 0);t&&Y(t)&&a&&(this._fetchFn=t,yield t(a)),this._queue&&T(this._queue)&&(this._currentQueueIndex=this._queue.findIndex(i=>i.id===(a==null?void 0:a.id)));try{a&&this.addMedia(a).then(()=>{r.HAVE_ENOUGH_DATA===v.HAVE_ENOUGH_DATA&&setTimeout(()=>p(this,null,function*(){this.attachEq(),yield this.play();}),950);});}catch(i){}})}pause(){r&&!(r!=null&&r.paused)&&(r==null||r.pause());}stop(){r&&!r.paused&&(r==null||r.pause(),r.currentTime=0);}reset(){return p(this,null,function*(){r&&(this.stop(),r.src="",r.srcObject=null);})}setVolume(e){let t=e/100;r&&(r.volume=t,N.notify("AUDIO_STATE",{volume:e}));}setPlaybackRate(e){r&&(r.playbackRate=e,N.notify("AUDIO_STATE",{playbackRate:e}));}mute(){r&&!r.muted&&(r.muted=!0);}seek(e){r&&(r.currentTime=e);}destroy(){return p(this,null,function*(){r&&(yield this.reset(),r.removeAttribute("src"),r.load());})}subscribe(e,t,a={}){return N.listen(e,t,a)}addEventListener(e,t){r.addEventListener(e,t);}getPresets(){return k.getPresets()}setPreset(e){this.eqInstance.setPreset(e);}setCustomEQ(e){this.eqInstance.setCustomEQ(e);}addQueue(e,t){let a=T(e)?e.slice():[];switch(t){case"DEFAULT":this._queue=a;break;case"REVERSE":this._queue=a.reverse();break;case"SHUFFLE":this._queue=$(a);break;default:this._queue=a;break}z();}playNext(){if(this._queue.length>this._currentQueueIndex+1){this._currentQueueIndex++;let e=this._queue[this._currentQueueIndex];this.addMediaAndPlay(e,this._fetchFn);}}playPrevious(){if(this._currentQueueIndex>0){this._currentQueueIndex--;let e=this._queue[this._currentQueueIndex];this.addMediaAndPlay(e,this._fetchFn);}}clearQueue(){this._queue&&T(this._queue)&&(this._queue=[]);}removeFromQueue(e){if(this._queue&&T(this._queue)){let t=this._queue.filter(a=>a.id==e.id);this._queue=t;}}getQueue(){return this._queue&&T(this._queue)?this._queue:[]}get id(){return r==null?void 0:r.getAttribute("id")}static getAudioInstance(){return r}},n(y,"AudioX"),u(y,"_instance"),y); +var V=Object.defineProperty;var B=Object.getOwnPropertySymbols;var oe=Object.prototype.hasOwnProperty,ne=Object.prototype.propertyIsEnumerable;var P=(s,e,t)=>e in s?V(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,R=(s,e)=>{for(var t in e||(e={}))oe.call(e,t)&&P(s,t,e[t]);if(B)for(var t of B(e))ne.call(e,t)&&P(s,t,e[t]);return s};var n=(s,e)=>V(s,"name",{value:e,configurable:!0});var u=(s,e,t)=>(P(s,typeof e!="symbol"?e+"":e,t),t);var p=(s,e,t)=>new Promise((a,r)=>{var o=A=>{try{h(t.next(A));}catch(S){r(S);}},d=A=>{try{h(t.throw(A));}catch(S){r(S);}},h=A=>A.done?a(A.value):Promise.resolve(A.value).then(o,d);h((t=t.apply(s,e)).next());});var K=[{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}],I=[{name:"Default",id:"default",default:!0,gains:[0,0,0,0,0,0,0,0,0,0]},{name:"Club",id:"club",default:!0,gains:[0,0,4.8,3.36,3.36,3.36,1.92,0,0,0]},{name:"Live",id:"live",default:!0,gains:[-2.88,0,2.4,3.36,3.36,3.36,2.4,1.44,1.44,1.44]},{name:"Party",id:"Party",default:!0,gains:[4.32,4.32,0,0,0,0,0,0,4.32,4.32]},{name:"Pop",id:"pop",default:!0,gains:[.96,2.88,4.32,4.8,3.36,0,-1.44,-1.44,.96,.96]},{name:"Soft",id:"soft",default:!0,gains:[2.88,.96,0,-1.44,0,2.4,4.8,5.76,6.72,7.2]},{name:"Ska",id:"ska",default:!0,gains:[-1.44,-2.88,-2.4,0,2.4,3.36,5.28,5.76,6.72,5.76]},{name:"Reggae",id:"reggae",default:!0,gains:[0,0,0,-3.36,0,3.84,3.84,0,0,0]},{name:"Rock",id:"rock",default:!0,gains:[4.8,2.88,-3.36,-4.8,-1.92,2.4,5.28,6.72,6.72,6.72]},{name:"Dance",id:"dance",default:!0,gains:[5.76,4.32,1.44,0,0,-3.36,-4.32,-4.32,0,0]},{name:"Techno",id:"techno",default:!0,gains:[4.8,3.36,0,-3.36,-2.88,0,4.8,5.76,5.76,5.28]},{name:"Headphones",id:"headphones",default:!0,gains:[2.88,6.72,3.36,-1.92,-1.44,.96,2.88,5.76,7.68,8.64]},{name:"Soft rock",id:"soft_rock",default:!0,gains:[2.4,2.4,1.44,0,-2.4,-3.36,-1.92,0,1.44,5.28]},{name:"Classical",id:"classical",default:!0,gains:[0,0,0,0,0,0,-4.32,-4.32,-4.32,-5.76]},{name:"Large Hall",id:"large_hall",default:!0,gains:[6.24,6.24,3.36,3.36,0,-2.88,-2.88,-2.88,0,0]},{name:"Full Bass",id:"full_base",default:!0,gains:[4.8,5.76,5.76,3.36,.96,-2.4,-4.8,-6.24,-6.72,-6.72]},{name:"Full Treble",id:"full_treble",default:!0,gains:[-5.76,-5.76,-5.76,-2.4,1.44,6.72,9.6,9.6,9.6,10.08]},{name:"Laptop Speakers",id:"laptop_speakers",default:!0,gains:[2.88,6.72,3.36,-1.92,-1.44,.96,2.88,5.76,7.68,8.64]},{name:"Full Bass & Treble",id:"bass_treble",default:!0,gains:[4.32,3.36,0,-4.32,-2.88,.96,4.8,6.72,7.2,7.2]}];var F=Object.freeze({REACT:"REACT",VANILLA:"VANILLA",DEVELOPMENT:"development"}),l=Object.freeze({BUFFERING:"buffering",PLAYING:"playing",PAUSED:"paused",READY:"ready",IDLE:"idle",ENDED:"ended",STALLED:"stalled",ERROR:"error",TRACK_CHANGE:"trackchanged",DURATION_CHANGE:"durationchanged"}),L=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."}),Y={HLS:"https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.11/hls.min.js",CAST:"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"};var E,le=(E=class{static validateEventName(e){if(!e||typeof e!="string")throw new Error("Invalid event name")}static notify(e,t,a="audiox_notifier_default"){this.validateEventName(e);let r=E.listeners[e];r&&t!==null&&(E.notifierState[e]=R(R({},E.notifierState[e]||{}),t),r.forEach(o=>{o(E.notifierState[e]);}));}static listen(e,t,a={}){if(this.validateEventName(e),typeof t!="function")throw new Error("Callback must be a function");return E.listeners[e]?E.listeners[e].add(t):(E.notifierState[e]=a,E.listeners[e]=new Set([t])),()=>{let r=E.listeners[e];r&&(r.delete(t),r.size===0&&delete E.listeners[e]);}}static multiListen(e,t,a={}){if(this.validateEventName(e),!Array.isArray(t)||t.length===0)throw new Error("Callbacks must be a non-empty array of functions");let r=t.map(o=>E.listen(e,o,a));return ()=>{r.forEach(o=>o());}}static getLatestState(e){return this.validateEventName(e),E.notifierState[e]}},n(E,"ChangeNotifier"),u(E,"listeners",{}),u(E,"notifierState",{}),E),f=le;var _=n(s=>s&&Array.isArray(s)&&s.length,"isValidArray"),Q=n(s=>s instanceof Function&&typeof s=="function","isValidFunction");var X={},j=n(s=>{let e="",t=s.error;switch(t==null?void 0:t.code){case MediaError.MEDIA_ERR_ABORTED:e+=L.MEDIA_ERR_ABORTED;break;case MediaError.MEDIA_ERR_NETWORK:e+=L.MEDIA_ERR_NETWORK;break;case MediaError.MEDIA_ERR_DECODE:e+=L.MEDIA_ERR_DECODE;break;case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:e+=L.MEDIA_ERR_SRC_NOT_SUPPORTED;break;default:e+=L.DEFAULT;break}return e},"getReadableErrorMessage"),z=n(s=>{var S;let{title:e,album:t,artist:a,artwork:r}=s,o=r?(S=r[0])==null?void 0:S.src:"",h=["96x96","128x128","192x192","256x256","384x384","512x512"].map(U=>({src:o,sizes:U,type:"image/png"}));return {title:e,album:t,artist:a,artwork:h}},"metaDataCreator"),k=0,b=n((s,e)=>{let t=new Set;for(let o=0;oo+d,0);k=["ENDED","TRACK_CHANGE","PAUSE"].includes(e)?r:k,f.notify("AUDIO_STATE",{currentTrackPlayTime:r,previousTrackPlayTime:k});},"calculateActualPlayedLength"),$=n((s,e,t)=>new Promise((a,r)=>{if(window instanceof Window&&window.document)if(X[t])e(),a();else {X[t]=!0;let o=document.createElement("script");o.type="text/javascript",o.src=s,o.async=!0,o.onload=()=>{e(),a();},document.head.appendChild(o);}else r(`Window not ready unable to initialize ${t}`);}),"loadScript"),W=n(()=>{let s=new T,e=!1,t=n(a=>{if(a.playbackState==="ended"&&!e){let r=s.getQueue();e=!0,r&&_(r)&&s.playNext();}a.playbackState!=="ended"&&(e=!1);},"audioStateListener");f.listen("AUDIO_STATE",t);},"handleQueuePlayback"),g=n(s=>{let{buffered:e}=s,t=0;for(let a=0;a{let e=[...s];for(let t=e.length-1;t>0;t--){let a=Math.floor(Math.random()*t);[e[t],e[a]]=[e[a],e[t]];}return e},"shuffle");var D,x=(D=class{constructor(){u(this,"audioCtx");u(this,"audioCtxStatus");u(this,"eqFilterBands");if(D._instance)return D._instance;this.initializeAudioContext(),D._instance=this;}initializeAudioContext(){typeof AudioContext!="undefined"?this.audioCtx=new AudioContext:typeof window.webkitAudioContext!="undefined"&&(this.audioCtx=new window.webkitAudioContext),this.audioCtxStatus="ACTIVE",this.init(),this.audioCtx.state==="suspended"&&this.addResumeListener();}addResumeListener(){let e=n(()=>{this.audioCtx.resume(),setTimeout(()=>{this.audioCtx.state==="running"&&document.body.removeEventListener("click",e,!1);},0);},"resume");document.body.addEventListener("click",e,!1);}init(){try{let e=T.getAudioInstance(),t=this.audioCtx.createMediaElementSource(e),a=K.map(o=>{let d=this.audioCtx.createBiquadFilter();return d.type=o.type,d.frequency.value=o.frequency,d.gain.value=o.gain,d.Q.value=1,d}),r=this.audioCtx.createGain();r.gain.value=1,t.connect(a[0]);for(let o=0;oa.id===e);t&&(!this.eqFilterBands||this.eqFilterBands.length!==t.gains.length||this.eqFilterBands.forEach((a,r)=>{a.gain.value=t.gains[r];}));}static getPresets(){return I}status(){return this.audioCtx.state==="suspended"&&this.audioCtx.resume(),this.audioCtxStatus}setCustomEQ(e){_(e)&&this.eqFilterBands.forEach((t,a)=>{t.gain.value=e[a];});}},n(D,"Equalizer"),u(D,"_instance"),D);var Z={ERROR:(s,e)=>{let t=e.type,a=e.details,r=e.fatal;f.notify("AUDIO_STATE",{playbackState:l.ERROR,error:{type:t,isFatal:r,detail:a}},`audiox_baseEvents_state_${s.type}`);},FRAG_CHANGED:()=>{}};var H=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"}),ee={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 w=n((s,e=!1)=>{let t=T.getAudioInstance();_(Object.keys(s))&&Object.keys(s).forEach(a=>{let r=a;t==null||t.addEventListener(H[r],o=>{if(a&&s[r]){let d=s[r];typeof d=="function"&&d(o,t,e);}});});},"attachEventListeners");var te=n((s,e=!1)=>{let a=new O().getHlsInstance();_(Object.keys(s))&&Object.keys(s).forEach(r=>{let o=r;a.on(ee[o],(d,h)=>{if(o&&s[o]){let A=s[o];typeof A=="function"&&A(d,h,a,e);}});});},"attachHlsEventsListeners");var C,y,ue=(y=class{constructor(){u(this,"HlsClass");if(y._instance)return y._instance;y._instance=this;}load(){return p(this,null,function*(){return yield $(Y.HLS,()=>{},"hls").then(()=>{this.HlsClass=window.Hls,window.Hls=void 0;}).catch(e=>{}),this.HlsClass})}init(){return p(this,arguments,function*(e={},t){let a=yield this.load();a.isSupported()&&(C=new a(e),te(Z,t));})}addHlsMedia(e){let t=this.HlsClass,a=T.getAudioInstance();C.loadSource(e.source),C.attachMedia(a),C.on(t.Events.MEDIA_ATTACHED,function(){});}getHlsInstance(){return C}},n(y,"HlsAdapter"),u(y,"_instance"),y),O=ue;var se=Object.freeze({1:"MEDIA_ERR_ABORTED",3:"MEDIA_ERR_DECODE",2:"MEDIA_ERR_NETWORK",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"});var c=f,ae={LOAD_START:(s,e)=>{let t=g(e);c.notify("AUDIO_STATE",{playbackState:l.BUFFERING,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""},bufferedDuration:t},`audiox_baseEvents_state_${s.type}`);},DURATION_CHANGE:(s,e)=>{let t=c.getLatestState("AUDIO_X_STATE"),a=g(e);c.notify("AUDIO_STATE",{playbackState:t.playbackState==="playing"?l.PLAYING:l.DURATION_CHANGE,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""},bufferedDuration:a},`audiox_baseEvents_state_${s.type}`);},LOADED_META_DATA:(s,e)=>{let t=g(e);c.notify("AUDIO_STATE",{playbackState:l.BUFFERING,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""},bufferedDuration:t},`audiox_baseEvents_state_${s.type}`);},LOADED_DATA:(s,e)=>{let t=g(e);c.notify("AUDIO_STATE",{playbackState:l.BUFFERING,duration:e==null?void 0:e.duration,error:{code:null,message:"",readable:""},bufferedDuration:t},`audiox_baseEvents_state_${s.type}`);},CAN_PLAY:(s,e)=>{let t=c.getLatestState("AUDIO_X_STATE"),a=g(e);c.notify("AUDIO_STATE",{playbackState:t.playbackState==="paused"?l.PAUSED:l.READY,error:{code:null,message:"",readable:""},bufferedDuration:a},`audiox_baseEvents_state_${s.type}`);},CAN_PLAY_THROUGH:(s,e)=>{let t=c.getLatestState("AUDIO_X_STATE"),a=e.paused,r=g(e);c.notify("AUDIO_STATE",{playbackState:a?l.PAUSED:t.playbackState==="playing"?l.PLAYING:l.READY,error:{code:null,message:"",readable:""},bufferedDuration:r},`audiox_baseEvents_state_${s.type}`);},PLAY:(s,e)=>{c.notify("AUDIO_STATE",{playbackState:l.PLAYING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},PLAYING:(s,e)=>{c.notify("AUDIO_STATE",{playbackState:l.PLAYING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},PAUSE:(s,e,t)=>{c.notify("AUDIO_STATE",{playbackState:l.PAUSED,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`),t&&b(e,"PAUSE");},ENDED:(s,e,t)=>{c.notify("AUDIO_STATE",{playbackState:l.ENDED,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`),t&&b(e,"ENDED");},ERROR:(s,e)=>{var r;let t=(r=e.error)==null?void 0:r.code,a=j(e);c.notify("AUDIO_STATE",{playbackState:l.ERROR,error:{code:t,message:se[t],readable:a}},`audiox_baseEvents_state_${s.type}`);},TIME_UPDATE:(s,e)=>{let t=c.getLatestState("AUDIO_X_STATE"),a=g(e);c.notify("AUDIO_STATE",{playbackState:e.paused?t==null?void 0:t.playbackState:l.PLAYING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""},bufferedDuration:a},`audiox_baseEvents_state_${s.type}`);},WAITING:(s,e)=>{c.notify("AUDIO_STATE",{playbackState:l.BUFFERING,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""}},`audiox_baseEvents_state_${s.type}`);},VOLUME_CHANGE:s=>{c.notify("AUDIO_STATE",{},"audiox_baseEvents_state");},SEEKED:(s,e)=>{let t=c.getLatestState("AUDIO_X_STATE"),a=g(e);c.notify("AUDIO_STATE",{playbackState:t.playbackState==="paused"?"paused":t.playbackState,progress:e==null?void 0:e.currentTime,error:{code:null,message:"",readable:""},bufferedDuration:a},`audiox_baseEvents_state_${s.type}`);}};var re=n(s=>{"mediaSession"in navigator&&(navigator.mediaSession.metadata=new MediaMetadata(z(s)));},"updateMetaData"),v=n(()=>{let s=new T;"mediaSession"in navigator&&(navigator.mediaSession.setActionHandler("play",()=>{T.getAudioInstance().play();}),navigator.mediaSession.setActionHandler("pause",()=>{T.getAudioInstance().pause();}),s.getQueue().length&&(navigator.mediaSession.setActionHandler("previoustrack",()=>{s.playPrevious();}),navigator.mediaSession.setActionHandler("nexttrack",()=>{s.playNext();})));},"attachMediaSessionHandlers");var M={HAVE_NOTHING:0,HAVE_METADATA:1,HAVE_CURRENT_DATA:2,HAVE_FUTURE_DATA:3,HAVE_ENOUGH_DATA:4},G={playbackState:l.IDLE,duration:0,bufferedDuration:0,progress:0,volume:50,playbackRate:1,error:{code:null,message:"",readable:""},currentTrack:{},currentTrackPlayTime:0,previousTrackPlayTime:0};f.listen("AUDIO_STATE",s=>{f.notify("AUDIO_X_STATE",R(R({},G),s));},G);var i,N=f,m,T=(m=class{constructor(){u(this,"_audio");u(this,"isPlayLogEnabled");u(this,"_queue");u(this,"_currentQueueIndex",0);u(this,"_fetchFn");u(this,"eqStatus","IDEAL");u(this,"isEqEnabled",!1);u(this,"eqInstance");u(this,"showNotificationsActions",!1);var e;if(m._instance)return m._instance;if(process.env.NODE_ENV!==((e=F)==null?void 0:e.DEVELOPMENT)&&i)throw new Error("Cannot create multiple audio instance");m._instance=this,this._audio=new Audio,i=this._audio;}init(e){return p(this,null,function*(){var q;let{preloadStrategy:t="auto",autoPlay:a=!1,useDefaultEventListeners:r=!0,customEventListeners:o=null,showNotificationActions:d=!1,enablePlayLog:h=!1,enableHls:A=!1,enableEQ:S=!1,crossOrigin:U="anonymous",hlsConfig:ie={}}=e;(q=this._audio)==null||q.setAttribute("id","audio_x_instance"),this._audio.preload=t,this._audio.autoplay=a,this._audio.crossOrigin=U,this.isPlayLogEnabled=h,o!==null?w(o,!1):w(ae,h),d&&(this.showNotificationsActions=!0,v()),S&&(this.isEqEnabled=S),A&&new O().init(ie,h);})}addMedia(e){return p(this,null,function*(){if(!e)return;let t=e.source.includes(".m3u8")?"HLS":"DEFAULT";if(this.isPlayLogEnabled&&b(i,"TRACK_CHANGE"),t==="HLS"){let a=new O,r=a.getHlsInstance();r?(r.detachMedia(),a.addHlsMedia(e)):yield this.reset();}else i.src=e.source;N.notify("AUDIO_STATE",{playbackState:l.TRACK_CHANGE,currentTrackPlayTime:0,currentTrack:e}),re(e),i.load();})}attachEq(){if(this.isEqEnabled&&this.eqStatus==="IDEAL")try{let e=new x;this.eqStatus=e.status(),this.eqInstance=e;}catch(e){}}play(){return p(this,null,function*(){let e=i.src!=="";i!=null&&i.paused&&i.HAVE_ENOUGH_DATA===M.HAVE_ENOUGH_DATA&&e&&(yield i.play().then(()=>{}).catch(()=>{}));})}addMediaAndPlay(e,t){return p(this,null,function*(){let a=e||(this._queue.length>0?this._queue[0]:void 0);t&&Q(t)&&a&&(this._fetchFn=t,yield t(a)),this._queue&&_(this._queue)&&(this._currentQueueIndex=this._queue.findIndex(r=>r.id===(a==null?void 0:a.id)));try{a&&this.addMedia(a).then(()=>{i.HAVE_ENOUGH_DATA===M.HAVE_ENOUGH_DATA&&setTimeout(()=>p(this,null,function*(){this.attachEq(),yield this.play();}),950);});}catch(r){}})}pause(){i&&!(i!=null&&i.paused)&&(i==null||i.pause());}stop(){i&&!i.paused&&(i==null||i.pause(),i.currentTime=0);}reset(){return p(this,null,function*(){i&&(this.stop(),i.src="",i.srcObject=null);})}setVolume(e){let t=e/100;i&&(i.volume=t,N.notify("AUDIO_STATE",{volume:e}));}setPlaybackRate(e){i&&(i.playbackRate=e,N.notify("AUDIO_STATE",{playbackRate:e}));}mute(){i&&!i.muted&&(i.muted=!0);}seek(e){i&&(i.currentTime=e);}seekBy(e){if(i&&i.currentTime){let t=i.currentTime;i.currentTime=t+e;}}destroy(){return p(this,null,function*(){i&&(yield this.reset(),i.removeAttribute("src"),i.load());})}subscribe(e,t,a={}){return N.listen(e,t,a)}addEventListener(e,t){i.addEventListener(e,t);}getPresets(){return x.getPresets()}setPreset(e){this.eqInstance.setPreset(e);}setCustomEQ(e){this.eqInstance.setCustomEQ(e);}addQueue(e,t){let a=_(e)?e.slice():[];switch(t){case"DEFAULT":this._queue=a;break;case"REVERSE":this._queue=a.reverse();break;case"SHUFFLE":this._queue=J(a);break;default:this._queue=a;break}W(),this.showNotificationsActions&&v();}playNext(){if(this._queue.length>this._currentQueueIndex+1){this._currentQueueIndex++;let e=this._queue[this._currentQueueIndex];this.addMediaAndPlay(e,this._fetchFn);}}playPrevious(){if(this._currentQueueIndex>0){this._currentQueueIndex--;let e=this._queue[this._currentQueueIndex];this.addMediaAndPlay(e,this._fetchFn);}}clearQueue(){this._queue&&_(this._queue)&&(this._queue=[]);}addToQueue(e){this._queue&&_(this._queue)&&(Array.isArray(e)?this._queue=[...this._queue,...e]:this._queue.push(e));}removeFromQueue(e){if(this._queue&&_(this._queue)){let t=this._queue.filter(a=>a.id==e.id);this._queue=t;}}getQueue(){return this._queue&&_(this._queue)?this._queue:[]}get id(){return i==null?void 0:i.getAttribute("id")}static getAudioInstance(){return i}},n(m,"AudioX"),u(m,"_instance"),m); -export { x as AUDIO_EVENTS, w as AUDIO_STATE, P as AUDIO_X_CONSTANTS, h as AudioX }; +export { H as AUDIO_EVENTS, G as AUDIO_STATE, F as AUDIO_X_CONSTANTS, T 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 index 658b011..ebf9aed 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +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","name","id","default","gains","AUDIO_X_CONSTANTS","Object","freeze","REACT","VANILLA","DEVELOPMENT","PLAYBACK_STATE","BUFFERING","PLAYING","PAUSED","READY","IDLE","ENDED","STALLED","ERROR","TRACK_CHANGE","DURATION_CHANGE","ERROR_MSG_MAP","MEDIA_ERR_ABORTED","MEDIA_ERR_DECODE","MEDIA_ERR_NETWORK","MEDIA_ERR_SRC_NOT_SUPPORTED","DEFAULT","URLS","HLS","CAST","_a","ChangeNotifier","validateEventName","eventName","Error","notify","data","caller","listenerCbs","listeners","notifierState","__spreadValues","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","isValidFunction","fn","Function","isValidWindow","window","undefined","Window","loadedScripts","getReadableErrorMessage","audioInstance","message","err","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","handleQueuePlayback","audio","AudioX","queue","getQueue","hasEnded","audioStateListener","playbackState","playNext","shuffle","array","shuffledArray","j","Math","floor","random","Equalizer","constructor","audioCtx","audioCtxStatus","eqFilterBands","_instance","initializeAudioContext","AudioContext","webkitAudioContext","init","addResumeListener","resume","setTimeout","body","removeEventListener","addEventListener","getAudioInstance","audioSource","createMediaElementSource","equalizerBands","band","filter","createBiquadFilter","value","Q","gainNode","createGain","connect","destination","setPreset","preset","find","index","getPresets","status","setCustomEQ","HLS_EVENTS_CALLBACK_MAP","e","detail","details","isFatal","fatal","FRAG_CHANGED","AUDIO_EVENTS","ABORT","TIME_UPDATE","CAN_PLAY","CAN_PLAY_THROUGH","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","attachEventListeners","eventListenersCallbackMap","playLogEnabled","keys","evt","listenerCallback","attachHlsEventsListeners","hlsEventlistenerCallbackMap","hlsInstance","HlsAdapter","getHlsInstance","on","HlsClass","load","__async","then","Hls","catch","msg","config","enablePlayLog","isSupported","addHlsMedia","loadSource","source","attachMedia","Events","hls_default","ERROR_EVENTS","notifier","BASE_EVENT_CALLBACK_MAP","duration","readable","audioState","progress","currentTime","errorCode","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","_queue","_currentQueueIndex","_fetchFn","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","fetchFn","findIndex","track","stop","srcObject","setVolume","actualVolume","setPlaybackRate","mute","muted","seek","time","destroy","removeAttribute","subscribe","addQueue","playbackType","playerQueue","slice","reverse","nextTrack","playPrevious","previousTrack","clearQueue","removeFromQueue","getAttribute"],"mappings":"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","sourcesContent":["import { Band } from 'types/equalizer.types';\n\nconst bands: Band[] = [\n { frequency: 31, type: 'lowshelf', gain: 0 },\n { frequency: 63, type: 'peaking', gain: 0 },\n { frequency: 125, type: 'peaking', gain: 0 },\n { frequency: 250, type: 'peaking', gain: 0 },\n { frequency: 500, type: 'peaking', gain: 0 },\n { frequency: 1000, type: 'peaking', gain: 0 },\n { frequency: 2000, type: 'peaking', gain: 0 },\n { frequency: 4000, type: 'peaking', gain: 0 },\n { frequency: 8000, type: 'peaking', gain: 0 },\n { frequency: 16000, type: 'highshelf', gain: 0 }\n];\n\nconst presets = [\n {\n name: 'Default',\n id: 'default',\n default: true,\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 name: 'Club',\n id: 'club',\n default: true,\n gains: [0.0, 0.0, 4.8, 3.36, 3.36, 3.36, 1.92, 0.0, 0.0, 0.0]\n },\n {\n name: 'Live',\n id: 'live',\n default: true,\n gains: [-2.88, 0.0, 2.4, 3.36, 3.36, 3.36, 2.4, 1.44, 1.44, 1.44]\n },\n {\n name: 'Party',\n id: 'Party',\n default: true,\n gains: [4.32, 4.32, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.32, 4.32]\n },\n {\n name: 'Pop',\n id: 'pop',\n default: true,\n gains: [0.96, 2.88, 4.32, 4.8, 3.36, 0.0, -1.44, -1.44, 0.96, 0.96]\n },\n {\n name: 'Soft',\n id: 'soft',\n default: true,\n gains: [2.88, 0.96, 0.0, -1.44, 0.0, 2.4, 4.8, 5.76, 6.72, 7.2]\n },\n {\n name: 'Ska',\n id: 'ska',\n default: true,\n gains: [-1.44, -2.88, -2.4, 0.0, 2.4, 3.36, 5.28, 5.76, 6.72, 5.76]\n },\n {\n name: 'Reggae',\n id: 'reggae',\n default: true,\n gains: [0.0, 0.0, 0.0, -3.36, 0.0, 3.84, 3.84, 0.0, 0.0, 0.0]\n },\n\n {\n name: 'Rock',\n id: 'rock',\n default: true,\n gains: [4.8, 2.88, -3.36, -4.8, -1.92, 2.4, 5.28, 6.72, 6.72, 6.72]\n },\n {\n name: 'Dance',\n id: 'dance',\n default: true,\n gains: [5.76, 4.32, 1.44, 0.0, 0.0, -3.36, -4.32, -4.32, 0.0, 0.0]\n },\n {\n name: 'Techno',\n id: 'techno',\n default: true,\n gains: [4.8, 3.36, 0.0, -3.36, -2.88, 0.0, 4.8, 5.76, 5.76, 5.28]\n },\n {\n name: 'Headphones',\n id: 'headphones',\n default: true,\n gains: [2.88, 6.72, 3.36, -1.92, -1.44, 0.96, 2.88, 5.76, 7.68, 8.64]\n },\n {\n name: 'Soft rock',\n id: 'soft_rock',\n default: true,\n gains: [2.4, 2.4, 1.44, 0.0, -2.4, -3.36, -1.92, 0.0, 1.44, 5.28]\n },\n {\n name: 'Classical',\n id: 'classical',\n default: true,\n gains: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.32, -4.32, -4.32, -5.76]\n },\n {\n name: 'Large Hall',\n id: 'large_hall',\n default: true,\n gains: [6.24, 6.24, 3.36, 3.36, 0.0, -2.88, -2.88, -2.88, 0.0, 0.0]\n },\n {\n name: 'Full Bass',\n id: 'full_base',\n default: true,\n gains: [4.8, 5.76, 5.76, 3.36, 0.96, -2.4, -4.8, -6.24, -6.72, -6.72]\n },\n {\n name: 'Full Treble',\n id: 'full_treble',\n default: true,\n gains: [-5.76, -5.76, -5.76, -2.4, 1.44, 6.72, 9.6, 9.6, 9.6, 10.08]\n },\n {\n name: 'Laptop Speakers',\n id: 'laptop_speakers',\n default: true,\n gains: [2.88, 6.72, 3.36, -1.92, -1.44, 0.96, 2.88, 5.76, 7.68, 8.64]\n },\n {\n name: 'Full Bass & Treble',\n id: 'bass_treble',\n default: true,\n gains: [4.32, 3.36, 0.0, -4.32, -2.88, 0.96, 4.8, 6.72, 7.2, 7.2]\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 DURATION_CHANGE: 'durationchanged'\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://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.11/hls.min.js',\n CAST: 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1'\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 { AudioX } from 'audio';\nimport { ERROR_MSG_MAP } from 'constants/common';\nimport { AudioEvents, AudioState, 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\nconst handleQueuePlayback = () => {\n const audio = new AudioX();\n const queue = audio.getQueue();\n let hasEnded = false;\n\n const audioStateListener = (state: AudioState) => {\n if (state.playbackState === 'ended' && !hasEnded) {\n hasEnded = true;\n if (queue && isValidArray(queue)) {\n audio.playNext();\n }\n }\n if (state.playbackState !== 'ended') {\n hasEnded = false;\n }\n };\n\n ChangeNotifier.listen('AUDIO_STATE', audioStateListener);\n};\n\nconst shuffle = (array: T[]): T[] => {\n const shuffledArray = [...array];\n\n for (let i = shuffledArray.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * i);\n\n [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];\n }\n\n return shuffledArray;\n};\n\nexport {\n getReadableErrorMessage,\n handleQueuePlayback,\n isValidArray,\n isValidFunction,\n isValidObject,\n isValidWindow,\n loadScript,\n metaDataCreator,\n shuffle\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 /**\n * Creates an instance of Equalizer or returns the existing instance.\n */\n constructor() {\n if (Equalizer._instance) {\n console.warn(\n 'Instantiation failed: cannot create multiple instances of Equalizer. Returning existing instance.'\n );\n return Equalizer._instance;\n }\n\n this.initializeAudioContext();\n\n Equalizer._instance = this;\n }\n\n /**\n * Initializes the AudioContext, ensuring compatibility with older browsers.\n * @private\n */\n private initializeAudioContext() {\n if (typeof AudioContext !== 'undefined') {\n this.audioCtx = new AudioContext();\n } else if (typeof (window as any).webkitAudioContext !== 'undefined') {\n this.audioCtx = new (window as any).webkitAudioContext();\n } else {\n console.error('Web Audio API is not supported in this browser.');\n }\n\n this.audioCtxStatus = 'ACTIVE';\n this.init();\n\n if (this.audioCtx.state === 'suspended') {\n this.addResumeListener();\n }\n }\n\n /**\n * Adds a listener to resume the AudioContext on user interaction.\n * @private\n */\n private addResumeListener() {\n const 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 /**\n * Initializes the equalizer by setting up the audio source and filter bands.\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; // TODO: 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 console.error('Equalizer initialization failed:', error);\n this.audioCtxStatus = 'FAILED';\n }\n }\n\n /**\n * Sets the equalizer to a predefined preset.\n * @param {keyof Preset} id - The ID of the preset to apply.\n */\n setPreset(id: keyof Preset) {\n const preset = presets.find((el) => el.id === id);\n if (!preset) {\n console.error('Preset not found:', id);\n return;\n }\n\n if (\n !this.eqFilterBands ||\n this.eqFilterBands.length !== preset.gains.length\n ) {\n console.error('Invalid data provided.');\n return;\n }\n\n this.eqFilterBands.forEach((band, index) => {\n band.gain.value = preset.gains[index];\n });\n }\n\n /**\n * Retrieves the list of available presets.\n * @returns {Preset[]} The list of available presets.\n */\n static getPresets() {\n return presets;\n }\n\n /**\n * Gets the current status of the AudioContext.\n * @returns {EqualizerStatus} The current status of the AudioContext.\n */\n status() {\n if (this.audioCtx.state === 'suspended') {\n this.audioCtx.resume();\n }\n return this.audioCtxStatus;\n }\n\n /**\n * Sets a custom equalizer configuration.\n * @param {number[]} gains - The gain values for each band.\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 } else {\n console.error('Invalid array of gains provided.');\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 attachEventListeners = (\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 attachEventListeners,\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.loadSource(mediaTrack.source);\n hlsInstance.attachMedia(audioInstance);\n hlsInstance.on(Hls.Events.MEDIA_ATTACHED, function () {\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';\n\nconst notifier = ChangeNotifier;\n\nconst BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = {\n LOAD_START: (e, 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_${e.type}`\n );\n },\n\n DURATION_CHANGE: (e, audioInstance: HTMLAudioElement) => {\n const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n console.log('STATUS', e.type);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState:\n audioState.playbackState === 'playing'\n ? PLAYBACK_STATE.PLAYING // fix for live streams where duration change is fired even when audio is playing\n : PLAYBACK_STATE.DURATION_CHANGE,\n duration: audioInstance?.duration,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\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_${e.type}`\n );\n },\n\n LOADED_DATA: (e, 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_${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.READY,\n error: { code: null, message: '', readable: '' }\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n CAN_PLAY_THROUGH: (e: Event) => {\n const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n console.log('STATUS', e.type);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState:\n audioState.playbackState === 'playing'\n ? PLAYBACK_STATE.PLAYING // fix for live streams as canplaythrough event is can be behave weirdly as there is no known end to the media\n : 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 PLAYING: (e, audioInstance) => {\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 = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n\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 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 (audioState: AudioState) => {\n ChangeNotifier.notify('AUDIO_X_STATE', { ...AUDIO_STATE, ...audioState });\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 { attachEventListeners } from 'events/listeners';\nimport {\n calculateActualPlayedLength,\n handleQueuePlayback,\n isValidArray,\n isValidFunction,\n shuffle\n} 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 {\n AudioInit,\n MediaTrack,\n PlaybackRate,\n QueuePlaybackType\n} 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 _queue: MediaTrack[];\n private _currentQueueIndex: number = 0;\n private _fetchFn: (mediaTrack: MediaTrack) => Promise;\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 (customEventListeners !== null) {\n if (useDefaultEventListeners) {\n console.warn(\n `useDefaultEventListeners is set to true at init, are you trying to use the default event listeners?\n set customEventListeners to null to use default event listeners`\n );\n }\n attachEventListeners(customEventListeners, false);\n } else {\n attachEventListeners(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(\n mediaTrack?: MediaTrack | null,\n fetchFn?: (mediaTrack: MediaTrack) => Promise\n // this should be passed when there something needs to be done before the audio starts playing\n ) {\n const currentTrack =\n mediaTrack || (this._queue.length > 0 ? this._queue[0] : undefined);\n if (fetchFn && isValidFunction(fetchFn) && currentTrack) {\n this._fetchFn = fetchFn;\n await fetchFn(currentTrack as MediaTrack);\n }\n if (this._queue && isValidArray(this._queue)) {\n this._currentQueueIndex = this._queue.findIndex(\n (track) => track.id === currentTrack?.id\n );\n }\n try {\n if (currentTrack) {\n this.addMedia(currentTrack).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 } else {\n console.error('Playback Failed, No MediaTrack Provided');\n }\n } catch (error) {\n console.error('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 addEventListener(\n event: keyof HTMLMediaElementEventMap,\n callback: (data: any) => void\n ) {\n audioInstance.addEventListener(event, callback);\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 addQueue(queue: MediaTrack[], playbackType: QueuePlaybackType) {\n const playerQueue = isValidArray(queue) ? queue.slice() : [];\n switch (playbackType) {\n case 'DEFAULT':\n this._queue = playerQueue;\n break;\n case 'REVERSE':\n this._queue = playerQueue.reverse();\n break;\n case 'SHUFFLE':\n this._queue = shuffle(playerQueue);\n break;\n default:\n this._queue = playerQueue;\n break;\n }\n handleQueuePlayback();\n }\n\n playNext() {\n if (this._queue.length > this._currentQueueIndex + 1) {\n this._currentQueueIndex++;\n const nextTrack = this._queue[this._currentQueueIndex];\n this.addMediaAndPlay(nextTrack, this._fetchFn);\n } else {\n console.warn('Queue ended');\n }\n }\n\n playPrevious() {\n if (this._currentQueueIndex > 0) {\n this._currentQueueIndex--;\n const previousTrack = this._queue[this._currentQueueIndex];\n this.addMediaAndPlay(previousTrack, this._fetchFn);\n } else {\n console.log('At the beginning of the queue');\n }\n }\n\n clearQueue() {\n if (this._queue && isValidArray(this._queue)) {\n this._queue = [];\n }\n }\n\n removeFromQueue(mediaTrack: MediaTrack) {\n if (this._queue && isValidArray(this._queue)) {\n const queue = this._queue.filter(\n (track: MediaTrack) => track.id == mediaTrack.id\n );\n this._queue = queue;\n }\n }\n\n getQueue() {\n return this._queue && isValidArray(this._queue) ? this._queue : [];\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 +{"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","name","id","default","gains","AUDIO_X_CONSTANTS","Object","freeze","REACT","VANILLA","DEVELOPMENT","PLAYBACK_STATE","BUFFERING","PLAYING","PAUSED","READY","IDLE","ENDED","STALLED","ERROR","TRACK_CHANGE","DURATION_CHANGE","ERROR_MSG_MAP","MEDIA_ERR_ABORTED","MEDIA_ERR_DECODE","MEDIA_ERR_NETWORK","MEDIA_ERR_SRC_NOT_SUPPORTED","DEFAULT","URLS","HLS","CAST","_a","ChangeNotifier","validateEventName","eventName","Error","notify","data","caller","listenerCbs","listeners","notifierState","__spreadValues","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","isValidFunction","fn","Function","isValidWindow","window","undefined","Window","loadedScripts","getReadableErrorMessage","audioInstance","message","err","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","handleQueuePlayback","audio","AudioX","hasEnded","audioStateListener","playbackState","queue","getQueue","playNext","getBufferedDuration","buffered","bufferedDuration","shuffle","array","shuffledArray","j","Math","floor","random","Equalizer","constructor","audioCtx","audioCtxStatus","eqFilterBands","_instance","initializeAudioContext","AudioContext","webkitAudioContext","init","addResumeListener","resume","setTimeout","body","removeEventListener","addEventListener","getAudioInstance","audioSource","createMediaElementSource","equalizerBands","band","filter","createBiquadFilter","value","Q","gainNode","createGain","connect","destination","setPreset","preset","find","index","getPresets","status","setCustomEQ","HLS_EVENTS_CALLBACK_MAP","e","detail","details","isFatal","fatal","FRAG_CHANGED","AUDIO_EVENTS","ABORT","TIME_UPDATE","CAN_PLAY","CAN_PLAY_THROUGH","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","attachEventListeners","eventListenersCallbackMap","playLogEnabled","keys","evt","listenerCallback","attachHlsEventsListeners","hlsEventlistenerCallbackMap","hlsInstance","HlsAdapter","getHlsInstance","on","HlsClass","load","__async","then","Hls","catch","msg","config","enablePlayLog","isSupported","addHlsMedia","loadSource","source","attachMedia","Events","hls_default","ERROR_EVENTS","notifier","BASE_EVENT_CALLBACK_MAP","duration","readable","audioState","isPaused","paused","progress","currentTime","errorCode","updateMetaData","navigator","mediaSession","metadata","MediaMetadata","attachMediaSessionHandlers","setActionHandler","play","pause","playPrevious","READY_STATE","HAVE_NOTHING","HAVE_METADATA","HAVE_CURRENT_DATA","HAVE_FUTURE_DATA","HAVE_ENOUGH_DATA","AUDIO_STATE","volume","playbackRate","currentTrack","_audio","isPlayLogEnabled","_queue","_currentQueueIndex","_fetchFn","eqStatus","isEqEnabled","eqInstance","showNotificationsActions","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","fetchFn","findIndex","track","stop","srcObject","setVolume","actualVolume","setPlaybackRate","mute","muted","seek","time","seekBy","currentProgress","destroy","removeAttribute","subscribe","addQueue","playbackType","playerQueue","slice","reverse","nextTrack","previousTrack","clearQueue","addToQueue","mediaTracks","push","removeFromQueue","getAttribute"],"mappings":"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","sourcesContent":["import { Band } from 'types/equalizer.types';\n\nconst bands: Band[] = [\n { frequency: 31, type: 'lowshelf', gain: 0 },\n { frequency: 63, type: 'peaking', gain: 0 },\n { frequency: 125, type: 'peaking', gain: 0 },\n { frequency: 250, type: 'peaking', gain: 0 },\n { frequency: 500, type: 'peaking', gain: 0 },\n { frequency: 1000, type: 'peaking', gain: 0 },\n { frequency: 2000, type: 'peaking', gain: 0 },\n { frequency: 4000, type: 'peaking', gain: 0 },\n { frequency: 8000, type: 'peaking', gain: 0 },\n { frequency: 16000, type: 'highshelf', gain: 0 }\n];\n\nconst presets = [\n {\n name: 'Default',\n id: 'default',\n default: true,\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 name: 'Club',\n id: 'club',\n default: true,\n gains: [0.0, 0.0, 4.8, 3.36, 3.36, 3.36, 1.92, 0.0, 0.0, 0.0]\n },\n {\n name: 'Live',\n id: 'live',\n default: true,\n gains: [-2.88, 0.0, 2.4, 3.36, 3.36, 3.36, 2.4, 1.44, 1.44, 1.44]\n },\n {\n name: 'Party',\n id: 'Party',\n default: true,\n gains: [4.32, 4.32, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.32, 4.32]\n },\n {\n name: 'Pop',\n id: 'pop',\n default: true,\n gains: [0.96, 2.88, 4.32, 4.8, 3.36, 0.0, -1.44, -1.44, 0.96, 0.96]\n },\n {\n name: 'Soft',\n id: 'soft',\n default: true,\n gains: [2.88, 0.96, 0.0, -1.44, 0.0, 2.4, 4.8, 5.76, 6.72, 7.2]\n },\n {\n name: 'Ska',\n id: 'ska',\n default: true,\n gains: [-1.44, -2.88, -2.4, 0.0, 2.4, 3.36, 5.28, 5.76, 6.72, 5.76]\n },\n {\n name: 'Reggae',\n id: 'reggae',\n default: true,\n gains: [0.0, 0.0, 0.0, -3.36, 0.0, 3.84, 3.84, 0.0, 0.0, 0.0]\n },\n\n {\n name: 'Rock',\n id: 'rock',\n default: true,\n gains: [4.8, 2.88, -3.36, -4.8, -1.92, 2.4, 5.28, 6.72, 6.72, 6.72]\n },\n {\n name: 'Dance',\n id: 'dance',\n default: true,\n gains: [5.76, 4.32, 1.44, 0.0, 0.0, -3.36, -4.32, -4.32, 0.0, 0.0]\n },\n {\n name: 'Techno',\n id: 'techno',\n default: true,\n gains: [4.8, 3.36, 0.0, -3.36, -2.88, 0.0, 4.8, 5.76, 5.76, 5.28]\n },\n {\n name: 'Headphones',\n id: 'headphones',\n default: true,\n gains: [2.88, 6.72, 3.36, -1.92, -1.44, 0.96, 2.88, 5.76, 7.68, 8.64]\n },\n {\n name: 'Soft rock',\n id: 'soft_rock',\n default: true,\n gains: [2.4, 2.4, 1.44, 0.0, -2.4, -3.36, -1.92, 0.0, 1.44, 5.28]\n },\n {\n name: 'Classical',\n id: 'classical',\n default: true,\n gains: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.32, -4.32, -4.32, -5.76]\n },\n {\n name: 'Large Hall',\n id: 'large_hall',\n default: true,\n gains: [6.24, 6.24, 3.36, 3.36, 0.0, -2.88, -2.88, -2.88, 0.0, 0.0]\n },\n {\n name: 'Full Bass',\n id: 'full_base',\n default: true,\n gains: [4.8, 5.76, 5.76, 3.36, 0.96, -2.4, -4.8, -6.24, -6.72, -6.72]\n },\n {\n name: 'Full Treble',\n id: 'full_treble',\n default: true,\n gains: [-5.76, -5.76, -5.76, -2.4, 1.44, 6.72, 9.6, 9.6, 9.6, 10.08]\n },\n {\n name: 'Laptop Speakers',\n id: 'laptop_speakers',\n default: true,\n gains: [2.88, 6.72, 3.36, -1.92, -1.44, 0.96, 2.88, 5.76, 7.68, 8.64]\n },\n {\n name: 'Full Bass & Treble',\n id: 'bass_treble',\n default: true,\n gains: [4.32, 3.36, 0.0, -4.32, -2.88, 0.96, 4.8, 6.72, 7.2, 7.2]\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 DURATION_CHANGE: 'durationchanged'\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://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.11/hls.min.js',\n CAST: 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1'\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 { AudioX } from 'audio';\nimport { ERROR_MSG_MAP } from 'constants/common';\nimport { AudioEvents, AudioState, 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\nconst handleQueuePlayback = () => {\n const audio = new AudioX();\n let hasEnded = false;\n\n const audioStateListener = (state: AudioState) => {\n if (state.playbackState === 'ended' && !hasEnded) {\n const queue = audio.getQueue();\n hasEnded = true;\n if (queue && isValidArray(queue)) {\n audio.playNext();\n }\n }\n if (state.playbackState !== 'ended') {\n hasEnded = false;\n }\n };\n\n ChangeNotifier.listen('AUDIO_STATE', audioStateListener);\n};\n\nconst getBufferedDuration = (audioInstance: HTMLAudioElement) => {\n const { buffered } = audioInstance;\n let bufferedDuration = 0;\n\n for (let i = 0; i < buffered.length; i++) {\n bufferedDuration += buffered.end(i) - buffered.start(i);\n }\n\n return bufferedDuration;\n};\n\nconst shuffle = (array: T[]): T[] => {\n const shuffledArray = [...array];\n\n for (let i = shuffledArray.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * i);\n\n [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];\n }\n\n return shuffledArray;\n};\n\nexport {\n getBufferedDuration,\n getReadableErrorMessage,\n handleQueuePlayback,\n isValidArray,\n isValidFunction,\n isValidObject,\n isValidWindow,\n loadScript,\n metaDataCreator,\n shuffle\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 /**\n * Creates an instance of Equalizer or returns the existing instance.\n */\n constructor() {\n if (Equalizer._instance) {\n console.warn(\n 'Instantiation failed: cannot create multiple instances of Equalizer. Returning existing instance.'\n );\n return Equalizer._instance;\n }\n\n this.initializeAudioContext();\n\n Equalizer._instance = this;\n }\n\n /**\n * Initializes the AudioContext, ensuring compatibility with older browsers.\n * @private\n */\n private initializeAudioContext() {\n if (typeof AudioContext !== 'undefined') {\n this.audioCtx = new AudioContext();\n } else if (typeof (window as any).webkitAudioContext !== 'undefined') {\n this.audioCtx = new (window as any).webkitAudioContext();\n } else {\n console.error('Web Audio API is not supported in this browser.');\n }\n\n this.audioCtxStatus = 'ACTIVE';\n this.init();\n\n if (this.audioCtx.state === 'suspended') {\n this.addResumeListener();\n }\n }\n\n /**\n * Adds a listener to resume the AudioContext on user interaction.\n * @private\n */\n private addResumeListener() {\n const 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 /**\n * Initializes the equalizer by setting up the audio source and filter bands.\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; // TODO: 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 console.error('Equalizer initialization failed:', error);\n this.audioCtxStatus = 'FAILED';\n }\n }\n\n /**\n * Sets the equalizer to a predefined preset.\n * @param {keyof Preset} id - The ID of the preset to apply.\n */\n setPreset(id: keyof Preset) {\n const preset = presets.find((el) => el.id === id);\n if (!preset) {\n console.error('Preset not found:', id);\n return;\n }\n\n if (\n !this.eqFilterBands ||\n this.eqFilterBands.length !== preset.gains.length\n ) {\n console.error('Invalid data provided.');\n return;\n }\n\n this.eqFilterBands.forEach((band, index) => {\n band.gain.value = preset.gains[index];\n });\n }\n\n /**\n * Retrieves the list of available presets.\n * @returns {Preset[]} The list of available presets.\n */\n static getPresets() {\n return presets;\n }\n\n /**\n * Gets the current status of the AudioContext.\n * @returns {EqualizerStatus} The current status of the AudioContext.\n */\n status() {\n if (this.audioCtx.state === 'suspended') {\n this.audioCtx.resume();\n }\n return this.audioCtxStatus;\n }\n\n /**\n * Sets a custom equalizer configuration.\n * @param {number[]} gains - The gain values for each band.\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 } else {\n console.error('Invalid array of gains provided.');\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 attachEventListeners = (\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 attachEventListeners,\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.loadSource(mediaTrack.source);\n hlsInstance.attachMedia(audioInstance);\n hlsInstance.on(Hls.Events.MEDIA_ATTACHED, function () {\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 getBufferedDuration,\n getReadableErrorMessage\n} from 'helpers/common';\nimport ChangeNotifier from 'helpers/notifier';\nimport { AudioState, EventListenerCallbackMap } from 'types';\nimport { ERROR_EVENTS } from './errorEvents';\n\nconst notifier = ChangeNotifier;\n\nconst BASE_EVENT_CALLBACK_MAP: EventListenerCallbackMap = {\n LOAD_START: (e, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const bufferedDuration = getBufferedDuration(audioInstance);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.BUFFERING,\n duration: audioInstance?.duration,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n DURATION_CHANGE: (e, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n const bufferedDuration = getBufferedDuration(audioInstance);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState:\n audioState.playbackState === 'playing'\n ? PLAYBACK_STATE.PLAYING // fix for live streams where duration change is fired even when audio is playing\n : PLAYBACK_STATE.DURATION_CHANGE,\n duration: audioInstance?.duration,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n LOADED_META_DATA: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const bufferedDuration = getBufferedDuration(audioInstance);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.BUFFERING,\n duration: audioInstance?.duration,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n LOADED_DATA: (e, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const bufferedDuration = getBufferedDuration(audioInstance);\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: PLAYBACK_STATE.BUFFERING,\n duration: audioInstance?.duration,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\n },\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n CAN_PLAY: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n const bufferedDuration = getBufferedDuration(audioInstance);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState:\n audioState.playbackState === 'paused'\n ? PLAYBACK_STATE.PAUSED\n : PLAYBACK_STATE.READY,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\n } as AudioState,\n `audiox_baseEvents_state_${e.type}`\n );\n },\n\n CAN_PLAY_THROUGH: (e: Event, audioInstance: HTMLAudioElement) => {\n console.log('STATUS', e.type);\n\n const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n const isPaused = audioInstance.paused;\n const bufferedDuration = getBufferedDuration(audioInstance);\n\n // below we check if the audio was already in paused state then we keep it as paused instead going to ready this make sure ready is fired only on the first load.\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState: isPaused\n ? PLAYBACK_STATE.PAUSED\n : audioState.playbackState === 'playing'\n ? PLAYBACK_STATE.PLAYING // fix for live streams as canplaythrough event is can be behave weirdly as there is no known end to the media\n : PLAYBACK_STATE.READY,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\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 PLAYING: (e, audioInstance) => {\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 = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n const bufferedDuration = getBufferedDuration(audioInstance);\n\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 bufferedDuration\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 SEEKED: (e: any, audioInstance: HTMLAudioElement) => {\n const audioState = notifier.getLatestState('AUDIO_X_STATE') as AudioState;\n const bufferedDuration = getBufferedDuration(audioInstance);\n\n notifier.notify(\n 'AUDIO_STATE',\n {\n playbackState:\n audioState.playbackState === 'paused'\n ? 'paused'\n : audioState.playbackState,\n progress: audioInstance?.currentTime,\n error: { code: null, message: '', readable: '' },\n bufferedDuration\n } as AudioState,\n `audiox_baseEvents_state_${e.type}`\n );\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 const audio = new AudioX();\n if ('mediaSession' in navigator) {\n navigator.mediaSession.setActionHandler('play', () => {\n const audioInstance = AudioX.getAudioInstance();\n audioInstance.play();\n });\n\n navigator.mediaSession.setActionHandler('pause', () => {\n const audioInstance = AudioX.getAudioInstance();\n audioInstance.pause();\n });\n\n // Only add next and previous handler if there is a valid queue\n if (audio.getQueue().length) {\n navigator.mediaSession.setActionHandler('previoustrack', () => {\n audio.playPrevious();\n });\n\n navigator.mediaSession.setActionHandler('nexttrack', () => {\n audio.playNext();\n });\n }\n }\n};\n\nexport const updatePositionState = () => {\n ChangeNotifier.listen('AUDIO_X_STATE', (audioState: AudioState) => {\n if (\n audioState?.duration &&\n audioState?.playbackRate &&\n audioState?.progress\n ) {\n navigator.mediaSession.setPositionState({\n duration: audioState.duration,\n playbackRate: audioState.playbackRate,\n position: audioState.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 (audioState: AudioState) => {\n ChangeNotifier.notify('AUDIO_X_STATE', { ...AUDIO_STATE, ...audioState });\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 { attachEventListeners } from 'events/listeners';\nimport {\n calculateActualPlayedLength,\n handleQueuePlayback,\n isValidArray,\n isValidFunction,\n shuffle\n} 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 {\n AudioInit,\n MediaTrack,\n PlaybackRate,\n QueuePlaybackType\n} 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 _queue: MediaTrack[];\n private _currentQueueIndex: number = 0;\n private _fetchFn: (mediaTrack: MediaTrack) => Promise;\n private eqStatus: EqualizerStatus = 'IDEAL';\n private isEqEnabled: boolean = false;\n private eqInstance: Equalizer;\n private showNotificationsActions: boolean = false;\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 (customEventListeners !== null) {\n if (useDefaultEventListeners) {\n console.warn(\n `useDefaultEventListeners is set to true at init, are you trying to use the default event listeners?\n set customEventListeners to null to use default event listeners`\n );\n }\n attachEventListeners(customEventListeners, false);\n } else {\n attachEventListeners(BASE_EVENT_CALLBACK_MAP, enablePlayLog);\n }\n\n if (showNotificationActions) {\n this.showNotificationsActions = true;\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(\n mediaTrack?: MediaTrack | null,\n fetchFn?: (mediaTrack: MediaTrack) => Promise\n // this should be passed when there something needs to be done before the audio starts playing\n ) {\n const currentTrack =\n mediaTrack || (this._queue.length > 0 ? this._queue[0] : undefined);\n if (fetchFn && isValidFunction(fetchFn) && currentTrack) {\n this._fetchFn = fetchFn;\n await fetchFn(currentTrack as MediaTrack);\n }\n\n if (this._queue && isValidArray(this._queue)) {\n this._currentQueueIndex = this._queue.findIndex(\n (track) => track.id === currentTrack?.id\n );\n }\n try {\n if (currentTrack) {\n this.addMedia(currentTrack).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 } else {\n console.error('Playback Failed, No MediaTrack Provided');\n }\n } catch (error) {\n console.error('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 seekBy(time: number) {\n if (audioInstance && audioInstance.currentTime) {\n const currentProgress = audioInstance.currentTime;\n audioInstance.currentTime = currentProgress + 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 addEventListener(\n event: keyof HTMLMediaElementEventMap,\n callback: (data: any) => void\n ) {\n audioInstance.addEventListener(event, callback);\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 addQueue(queue: MediaTrack[], playbackType: QueuePlaybackType) {\n const playerQueue = isValidArray(queue) ? queue.slice() : [];\n switch (playbackType) {\n case 'DEFAULT':\n this._queue = playerQueue;\n break;\n case 'REVERSE':\n this._queue = playerQueue.reverse();\n break;\n case 'SHUFFLE':\n this._queue = shuffle(playerQueue);\n break;\n default:\n this._queue = playerQueue;\n break;\n }\n handleQueuePlayback();\n // Attaching MediaSession Handler again as this will make sure the next and previous button show up in notification\n if (this.showNotificationsActions) {\n attachMediaSessionHandlers();\n }\n }\n\n playNext() {\n if (this._queue.length > this._currentQueueIndex + 1) {\n this._currentQueueIndex++;\n const nextTrack = this._queue[this._currentQueueIndex];\n this.addMediaAndPlay(nextTrack, this._fetchFn);\n } else {\n console.warn('Queue ended');\n }\n }\n\n playPrevious() {\n if (this._currentQueueIndex > 0) {\n this._currentQueueIndex--;\n const previousTrack = this._queue[this._currentQueueIndex];\n this.addMediaAndPlay(previousTrack, this._fetchFn);\n } else {\n console.log('At the beginning of the queue');\n }\n }\n\n clearQueue() {\n if (this._queue && isValidArray(this._queue)) {\n this._queue = [];\n }\n }\n\n addToQueue(mediaTracks: MediaTrack | MediaTrack[]) {\n if (this._queue && isValidArray(this._queue)) {\n if (Array.isArray(mediaTracks)) {\n this._queue = [...this._queue, ...mediaTracks];\n } else {\n this._queue.push(mediaTracks);\n }\n }\n }\n\n removeFromQueue(mediaTrack: MediaTrack) {\n if (this._queue && isValidArray(this._queue)) {\n const queue = this._queue.filter(\n (track: MediaTrack) => track.id == mediaTrack.id\n );\n this._queue = queue;\n }\n }\n\n getQueue() {\n return this._queue && isValidArray(this._queue) ? this._queue : [];\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 diff --git a/package.json b/package.json index 58d70c2..ba9fd6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "audio_x", - "version": "1.0.8", + "version": "1.0.9", "description": "The audio player for the gen-x", "main": "./dist/index.js", "types": "./dist/index.d.ts",