Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

web-audio-api-player

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

web-audio-api-player - npm Package Compare versions

Comparing version 5.1.0 to 5.1.1

124

dist/index.js

@@ -147,4 +147,3 @@ /******************************************************************************

}
const currentTimeRounded = Math.round((currentTime + Number.EPSILON) * 100) / 100;
return currentTimeRounded;
return currentTime;
}

@@ -161,4 +160,3 @@ getDuration() {

}
const durationRounded = Math.round((duration + Number.EPSILON) * 100) / 100;
return durationRounded;
return duration;
}

@@ -306,3 +304,3 @@ setDuration(duration) {

audioElement.autoplay = false;
audioElement.preload = 'metadata';
audioElement.preload = 'auto';
audioElement.volume = 1;

@@ -490,3 +488,8 @@ audioElement.id = 'web-audio-api-player';

const timeConstantInSeconds = timeConstantInMilliseconds / 1000;
this._audioNodes.gainNode.gain.setTargetAtTime(gainValue, audioContext.currentTime, timeConstantInSeconds);
try {
this._audioNodes.gainNode.gain.setTargetAtTime(gainValue, audioContext.currentTime, timeConstantInSeconds);
}
catch (error) {
console.error('gainValue: ' + gainValue + ' ' + error);
}
}

@@ -516,14 +519,16 @@ });

}
else {
if (this._options.persistVolume) {
const userVolumeInPercent = parseInt(localStorage.getItem('WebAudioAPIPlayerVolume'));
if (!isNaN(userVolumeInPercent)) {
volume = userVolumeInPercent;
}
}
if (typeof volume === 'undefined') {
else if (this._options.persistVolume) {
const userVolumeInPercent = parseInt(localStorage.getItem('WebAudioAPIPlayerVolume'));
volume = userVolumeInPercent;
}
if (typeof volume === 'undefined' || isNaN(volume)) {
if (!isNaN(this._options.volume)) {
volume = this._options.volume;
}
this._volume = volume;
else {
volume = 80;
console.error('player options volume is not a number');
}
}
this._volume = volume;
return volume;

@@ -750,4 +755,4 @@ }

if (currentSound !== null) {
if (!isNaN(currentSound.duration) && (soundPositionInSeconds > Math.ceil(currentSound.duration))) {
console.warn('soundPositionInSeconds > sound duration');
if (!isNaN(currentSound.duration) && (soundPositionInSeconds >= currentSound.duration)) {
soundPositionInSeconds = currentSound.duration - 0.1;
}

@@ -794,3 +799,3 @@ if (currentSound.onSeeking !== null) {

_loadSoundUsingAudioElement(sound) {
return new Promise((resolve, reject) => {
return __awaiter(this, void 0, void 0, function* () {
const { url, codec = null } = this._findBestSource(sound.source);

@@ -800,40 +805,35 @@ sound.url = url;

if (sound.url !== null) {
this._playerAudio.getAudioElement().then((audioElement) => {
sound.audioElement = audioElement;
const canPlayThroughHandler = () => __awaiter(this, void 0, void 0, function* () {
sound.audioElement.removeEventListener('canplaythrough', canPlayThroughHandler);
sound.isReadyToPLay = true;
if (!isNaN(sound.audioElement.duration) && !sound.durationSetManually) {
sound.duration = sound.audioElement.duration;
sound.audioElement = yield this._playerAudio.getAudioElement();
sound.audioElement.onprogress = () => {
if (sound.audioElement.buffered.length) {
const duration = sound.getDuration();
const buffered = sound.audioElement.buffered.end(0);
const loadingPercentageRaw = 100 / (duration / buffered);
const loadingPercentage = Math.round(loadingPercentageRaw);
sound.loadingProgress = loadingPercentage;
if (sound.onLoading !== null) {
sound.onLoading(loadingPercentage, duration, buffered);
}
return resolve();
});
sound.audioElement.addEventListener('canplaythrough', canPlayThroughHandler);
sound.audioElement.onprogress = () => {
if (sound.audioElement.buffered.length) {
const duration = sound.getDuration();
const buffered = sound.audioElement.buffered.end(0);
const loadingPercentageRaw = 100 / (duration / buffered);
const loadingPercentage = Math.round(loadingPercentageRaw);
sound.loadingProgress = loadingPercentage;
if (sound.onLoading !== null) {
sound.onLoading(loadingPercentage, duration, buffered);
}
if (!sound.durationSetManually) {
sound.duration = sound.audioElement.duration;
}
if (loadingPercentage === 100) {
sound.isBuffering = false;
sound.isBuffered = true;
sound.audioBufferDate = new Date();
}
if (loadingPercentage === 100) {
sound.isBuffering = false;
sound.isBuffered = true;
sound.audioBufferDate = new Date();
}
};
sound.audioElement.crossOrigin = 'anonymous';
sound.audioElement.src = sound.url;
sound.audioElement.load();
}).catch(reject);
}
};
const canPlayThroughHandler = () => __awaiter(this, void 0, void 0, function* () {
sound.audioElement.removeEventListener('canplaythrough', canPlayThroughHandler);
sound.isReadyToPLay = true;
if (!isNaN(sound.audioElement.duration) && !sound.durationSetManually) {
sound.duration = sound.audioElement.duration;
}
yield this._play(sound);
});
sound.audioElement.addEventListener('canplaythrough', canPlayThroughHandler);
sound.audioElement.crossOrigin = 'anonymous';
sound.audioElement.src = sound.url;
sound.audioElement.load();
}
else {
reject(new Error('sound has no url'));
throw new Error('sound has no url');
}

@@ -874,9 +874,5 @@ });

sound.isReadyToPLay = true;
yield this._play(sound);
});
}
manuallyUnlockAudio() {
return __awaiter(this, void 0, void 0, function* () {
yield this._playerAudio.unlockAudio();
});
}
play({ whichSound, playTimeOffset } = {}) {

@@ -887,3 +883,2 @@ return __awaiter(this, void 0, void 0, function* () {

if (sound === null) {
console.warn('no more sounds in array');
return sound;

@@ -920,3 +915,2 @@ }

yield this._loadSound(sound);
yield this._play(sound);
}

@@ -931,2 +925,5 @@ else {

return __awaiter(this, void 0, void 0, function* () {
if (sound.state === PlayerSound.SOUND_STATE_PLAYING) {
return;
}
if (this._playerAudio.isAudioContextFrozen()) {

@@ -1039,3 +1036,5 @@ yield this._playerAudio.unfreezeAudioContext();

try {
yield this.next();
if (willPlayNext) {
yield this.next();
}
}

@@ -1336,2 +1335,7 @@ catch (error) {

}
manuallyUnlockAudio() {
return __awaiter(this, void 0, void 0, function* () {
yield this._playerAudio.unlockAudio();
});
}
disconnect() {

@@ -1338,0 +1342,0 @@ return __awaiter(this, void 0, void 0, function* () {

@@ -1,2 +0,2 @@

function e(e,t,i,o){return new(i||(i=Promise))((function(n,u){function s(e){try{r(o.next(e))}catch(e){u(e)}}function d(e){try{r(o.throw(e))}catch(e){u(e)}}function r(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(s,d)}r((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(e){this.url=null,this.codec=null,this.loop=!1,this.sourceNode=null,this.gainNode=null,this.isReadyToPLay=!1,this.isBuffered=!1,this.isBuffering=!1,this.audioElement=null,this.audioBuffer=null,this.arrayBuffer=null,this.audioBufferDate=null,this.playTimeOffset=0,this.startTime=0,this.elapsedPlayTime=0,this.playTime=0,this.playedTimePercentage=0,this.state="sound_state_stopped",this.loadingProgress=0,this.duration=null,this.durationSetManually=!1,this.firstTimePlayed=!0,this.isConnectToPlayerGain=!1,Array.isArray(e.source)?this.source=e.source:this.source=[e.source],void 0!==e.id?this.id=e.id:this.id=this._generateSoundId(),this.loop=e.loop||!1,isNaN(e.duration)||(this.duration=e.duration,this.durationSetManually=!0),"function"==typeof e.onLoading?this.onLoading=e.onLoading:this.onLoading=null,"function"==typeof e.onPlaying?this.onPlaying=e.onPlaying:this.onPlaying=null,"function"==typeof e.onStarted?this.onStarted=e.onStarted:this.onStarted=null,"function"==typeof e.onEnded?this.onEnded=e.onEnded:this.onEnded=null,"function"==typeof e.onStopped?this.onStopped=e.onStopped:this.onStopped=null,"function"==typeof e.onPaused?this.onPaused=e.onPaused:this.onPaused=null,"function"==typeof e.onResumed?this.onResumed=e.onResumed:this.onResumed=null,"function"==typeof e.onSeeking?this.onSeeking=e.onSeeking:this.onSeeking=null,e.arrayBuffer instanceof ArrayBuffer&&(this.arrayBuffer=e.arrayBuffer),e.audioBuffer instanceof AudioBuffer&&(this.audioBuffer=e.audioBuffer,this.isBuffering=!1,this.isBuffered=!0,this.audioBufferDate=new Date,this.durationSetManually||(this.duration=this.audioBuffer.duration))}getCurrentTime(){let e;null!==this.sourceNode&&(this.sourceNode instanceof AudioBufferSourceNode?e=this.sourceNode.context.currentTime-this.startTime+this.elapsedPlayTime:this.sourceNode instanceof MediaElementAudioSourceNode&&(e=this.audioElement.currentTime));return Math.round(100*(e+Number.EPSILON))/100}getDuration(){let e;null!==this.sourceNode&&(this.sourceNode instanceof AudioBufferSourceNode?e=this.audioBuffer.duration:this.sourceNode instanceof MediaElementAudioSourceNode&&(e=this.audioElement.duration));return Math.round(100*(e+Number.EPSILON))/100}setDuration(e){isNaN(e)||(this.duration=e,this.durationSetManually=!0)}setLoop(e){this.loop=e,this.state===t.SOUND_STATE_PLAYING&&null!==this.sourceNode&&(this.sourceNode instanceof AudioBufferSourceNode?this.sourceNode.loop=e:this.sourceNode instanceof MediaElementAudioSourceNode&&(this.sourceNode.mediaElement.loop=e))}getLoop(){return this.loop}_generateSoundId(){return Date.now().toString(36)+Math.random().toString(36).substring(2)}}t.SOUND_STATE_STOPPED="sound_state_stopped",t.SOUND_STATE_PAUSED="sound_state_paused",t.SOUND_STATE_PLAYING="sound_state_playing",t.SOUND_STATE_SEEKING="sound_state_seeking";class i{constructor(e){this._audioContext=null,this._volume=null,this._audioNodes={gainNode:null},this._audioElement=null,this._mediaElementAudioSourceNode=null,this._isAudioUnlocked=!1,this._isAudioUnlocking=!1,this._options=e,this._initialize()}_initialize(){this._options.unlockAudioOnFirstUserInteraction&&this._addFirstUserInteractionEventListeners()}getAudioNodes(){return this._audioNodes}decodeAudio(t){return e(this,void 0,void 0,(function*(){const e=yield this.getAudioContext();return yield e.decodeAudioData(t)}))}_createAudioContext(){if(this._audioContext instanceof AudioContext)return;const e=window.AudioContext||window.webkitAudioContext;null!==this._options.audioContext?this._audioContext=this._options.audioContext:this._audioContext=new e}_addFirstUserInteractionEventListeners(){this._options.unlockAudioOnFirstUserInteraction&&(document.addEventListener("keydown",this.unlockAudio.bind(this)),document.addEventListener("mousedown",this.unlockAudio.bind(this)),document.addEventListener("pointerdown",this.unlockAudio.bind(this)),document.addEventListener("pointerup",this.unlockAudio.bind(this)),document.addEventListener("touchend",this.unlockAudio.bind(this)))}_removeFirstUserInteractionEventListeners(){this._options.unlockAudioOnFirstUserInteraction&&(document.removeEventListener("keydown",this.unlockAudio.bind(this)),document.removeEventListener("mousedown",this.unlockAudio.bind(this)),document.removeEventListener("pointerdown",this.unlockAudio.bind(this)),document.removeEventListener("pointerup",this.unlockAudio.bind(this)),document.removeEventListener("touchend",this.unlockAudio.bind(this)))}unlockAudio(){return new Promise(((e,t)=>{if(this._isAudioUnlocking)return e();if(this._isAudioUnlocked)return e();if(this._isAudioUnlocking=!0,"player_mode_audio"===this._options.loadPlayerMode){const e=!0;this._createAudioElement(e).catch((e=>(this._isAudioUnlocking=!1,t())))}this.getAudioContext().then((()=>{const t=this._audioContext.createBuffer(1,1,22050);let i=this._audioContext.createBufferSource();i.onended=()=>(i.disconnect(0),this._removeFirstUserInteractionEventListeners(),i.disconnect(0),i.buffer=null,i=null,this._isAudioUnlocked=!0,this._isAudioUnlocking=!1,e()),i.buffer=t,i.connect(this._audioContext.destination),i.start(0)})).catch((e=>(this._isAudioUnlocking=!1,t())))}))}_createAudioElementAndSource(){return e(this,void 0,void 0,(function*(){yield this._createAudioElement(),yield this._createMediaElementAudioSourceNode()}))}_createAudioElement(t){return e(this,void 0,void 0,(function*(){if(null===this._audioElement||!0===t){const e=new Audio;e.controls=!1,e.autoplay=!1,e.preload="metadata",e.volume=1,e.id="web-audio-api-player",this._audioElement=e,this._options.addAudioElementsToDom&&document.body.appendChild(e)}}))}getAudioElement(){return e(this,void 0,void 0,(function*(){return null===this._audioElement&&(yield this._createAudioElementAndSource()),this._audioElement}))}getAudioContext(){return e(this,void 0,void 0,(function*(){return null===this._audioContext||"closed"===this._audioContext.state?yield this._createAudioContext():"suspended"===this._audioContext.state&&(yield this.unfreezeAudioContext()),this._audioContext}))}unfreezeAudioContext(){return void 0===this._audioContext.resume?Promise.resolve():this._audioContext.resume()}freezeAudioContext(){return void 0===this._audioContext.suspend?Promise.resolve():this._audioContext.suspend()}isAudioContextFrozen(){return"suspended"===this._audioContext.state}detectAudioContextSupport(){let e=!1;return(void 0!==window.webkitAudioContext||"undefined"!=typeof AudioContext)&&(e=!0),e}detectAudioElementSupport(){return!!document.createElement("audio").canPlayType}_createAudioBufferSourceNode(){return e(this,void 0,void 0,(function*(){return(yield this.getAudioContext()).createBufferSource()}))}_createMediaElementAudioSourceNode(){return e(this,void 0,void 0,(function*(){if(null===this._mediaElementAudioSourceNode&&null!==this._audioElement){const e=yield this.getAudioContext();this._mediaElementAudioSourceNode=e.createMediaElementSource(this._audioElement)}}))}_destroyMediaElementAudioSourceNode(){null!==this._mediaElementAudioSourceNode&&(void 0!==this._mediaElementAudioSourceNode.mediaElement&&this._mediaElementAudioSourceNode.mediaElement.remove(),this._mediaElementAudioSourceNode.disconnect(),this._mediaElementAudioSourceNode=null)}_destroyAudioBufferSourceNode(){null!==this._mediaElementAudioSourceNode&&this._mediaElementAudioSourceNode.disconnect()}_destroyAudioContext(){return e(this,void 0,void 0,(function*(){null!==this._audioContext&&"closed"!==this._audioContext.state&&(yield this._audioContext.close(),this._audioContext=null)}))}shutDown(t){return e(this,void 0,void 0,(function*(){this._removeFirstUserInteractionEventListeners(),t.forEach((e=>{this.disconnectSound(e)})),this._destroyMediaElementAudioSourceNode(),this._destroyAudioBufferSourceNode(),this._disconnectPlayerGainNode(),yield this._destroyAudioContext()}))}_getPlayerGainNode(){return e(this,void 0,void 0,(function*(){let e;if(this._audioNodes.gainNode instanceof GainNode)e=this._audioNodes.gainNode;else{const t=yield this.getAudioContext();e=t.createGain(),this._initializeVolume(e),e.connect(t.destination),this._audioNodes.gainNode=e}return e}))}_disconnectPlayerGainNode(){null!==this._audioNodes.gainNode&&(this._audioNodes.gainNode.disconnect(),this._audioNodes.gainNode=null)}connectSound(t,i){return e(this,void 0,void 0,(function*(){if(t.isConnectToPlayerGain)return;if("player_mode_ajax"===this._options.loadPlayerMode){const e=yield this._createAudioBufferSourceNode();t.gainNode=e.context.createGain(),e.connect(t.gainNode),e.loop=t.loop,e.onended=i,t.sourceNode=e}else"player_mode_audio"===this._options.loadPlayerMode&&(yield this._createAudioElementAndSource(),t.gainNode=this._mediaElementAudioSourceNode.context.createGain(),this._mediaElementAudioSourceNode.connect(t.gainNode),this._mediaElementAudioSourceNode.mediaElement.loop=t.loop,this._mediaElementAudioSourceNode.mediaElement.onended=i,t.sourceNode=this._mediaElementAudioSourceNode);t.gainNode.gain.value=1;const e=yield this._getPlayerGainNode();t.gainNode.connect(e),t.isConnectToPlayerGain=!0}))}disconnectSound(t){return e(this,void 0,void 0,(function*(){t.isConnectToPlayerGain&&(null!==t.sourceNode&&(t.sourceNode.disconnect(),t.sourceNode=null),null!==t.gainNode&&(t.gainNode.disconnect(),t.gainNode=null,t.isConnectToPlayerGain=!1),null!==t.audioElement&&(t.audioElement=null))}))}_changePlayerGainValue(t){return e(this,void 0,void 0,(function*(){if(this._audioNodes.gainNode instanceof GainNode){const e=yield this.getAudioContext(),i=(!isNaN(this._options.volumeTransitionTime)&&this._options.volumeTransitionTime>0?this._options.volumeTransitionTime:100)/1e3;this._audioNodes.gainNode.gain.setTargetAtTime(t,e.currentTime,i)}}))}setVolume(t,i=!0){return e(this,void 0,void 0,(function*(){this._options.persistVolume&&i&&localStorage.setItem("WebAudioAPIPlayerVolume",t.toString());const e=t/100;if(this._audioNodes.gainNode instanceof GainNode){e!==Math.round(100*(this._audioNodes.gainNode.gain.value+Number.EPSILON))/100&&(yield this._changePlayerGainValue(e))}return this._volume=t,t}))}getVolume(){let e;if(null!==this._volume)e=this._volume;else{if(this._options.persistVolume){const t=parseInt(localStorage.getItem("WebAudioAPIPlayerVolume"));isNaN(t)||(e=t)}void 0===e&&(e=this._options.volume),this._volume=e}return e}_initializeVolume(e){if(this._options.persistVolume){const t=parseInt(localStorage.getItem("WebAudioAPIPlayerVolume")),i=t/100;isNaN(t)||(e.gain.value=i),this._volume=t}if(null===this._volume){const t=this._options.volume/100;e.gain.value=t,this._volume=this._options.volume}}}class o{getArrayBuffer(e){return new Promise((function(t,i){const o=new XMLHttpRequest;o.open("GET",e.url,!0),o.responseType="arraybuffer",o.onload=function(){o.status>=200&&o.status<=299?t(o.response):i(new Error(o.statusText+"(status:"+o.status+")"))},o.onprogress=function(t){const i=100/(t.total/t.loaded),o=Math.round(i);e.loadingProgress=o,null!==e.onLoading&&e.onLoading(o,t.total,t.loaded)},o.onerror=function(e){i(e)},o.send()}))}}class n{constructor(e={}){this._playingProgressRequestId=null,this._postMuteVolume=null,this._progressTrigger=(e,i)=>{const o=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(e.id===o.id&&o.state===t.SOUND_STATE_PLAYING){if(i-this._playingProgressPreviousTimestamp>=this._options.playingProgressIntervalTime){const t=e.getCurrentTime(),o=e.getDuration();if(!isNaN(t)&&!isNaN(o)){let n=0;if(0!==t){const e=t/o*100;n=Math.round(e)}e.playedTimePercentage=n,e.playTime=t,e.onPlaying(n,o,t),this._playingProgressPreviousTimestamp=i}}this._playingProgressRequestId=window.requestAnimationFrame((t=>{this._progressTrigger(e,t)}))}};const i={volume:80,loopQueue:!1,loopSong:!1,soundsBaseUrl:"",playingProgressIntervalTime:200,playNextOnEnded:!0,stopOnReset:!0,visibilityAutoMute:!1,unlockAudioOnFirstUserInteraction:!1,persistVolume:!0,loadPlayerMode:"player_mode_audio",audioContext:null,addAudioElementsToDom:!1,volumeTransitionTime:100},o=Object.assign({},i,e);this._queue=[],this._currentIndex=0,this._options=o,this._playingProgressPreviousTimestamp=0,this._initialize()}_initialize(){const e=this._audioOptions();switch(this._playerAudio=new i(e),this._options.loadPlayerMode){case n.PLAYER_MODE_AUDIO:if(!this._playerAudio.detectAudioContextSupport())throw new Error("audio context is not supported by this device");if(!this._playerAudio.detectAudioElementSupport())throw new Error("audio element is not supported by this device");break;case n.PLAYER_MODE_AJAX:if(!this._playerAudio.detectAudioContextSupport())throw new Error("audio context is not supported by this device")}}_audioOptions(){return{audioContext:this._options.audioContext,unlockAudioOnFirstUserInteraction:this._options.unlockAudioOnFirstUserInteraction,volume:this._options.volume,persistVolume:this._options.persistVolume,loadPlayerMode:this._options.loadPlayerMode,addAudioElementsToDom:this._options.addAudioElementsToDom,volumeTransitionTime:this._options.volumeTransitionTime}}addSoundToQueue({soundAttributes:e,whereInQueue:i="append"}){const o=new t(e);switch(i){case n.WHERE_IN_QUEUE_AT_END:this._appendSoundToQueue(o);break;case n.WHERE_IN_QUEUE_AT_START:this._prependSoundToQueue(o)}return o}_appendSoundToQueue(e){this._queue.push(e)}_prependSoundToQueue(e){this._queue.unshift(e)}resetQueue(){return e(this,void 0,void 0,(function*(){this._options.stopOnReset&&(yield this.stop()),this._queue.forEach((e=>{this._playerAudio.disconnectSound(e)})),this._queue=[]}))}reset(){this.resetQueue().catch((e=>{}))}getQueue(){return this._queue}setVolume(e){this._playerAudio.setVolume(e).catch((e=>{}))}getVolume(){return this._playerAudio.getVolume()}setLoopQueue(e){this._options.loopQueue=e}getLoopQueue(){return this._options.loopQueue}mute(){const e=this.getVolume();this._playerAudio.setVolume(0,!1).catch((e=>{})),this._postMuteVolume=e}unMute(){this._playerAudio.setVolume(this._postMuteVolume,!1).catch((e=>{})),this._postMuteVolume=null}isMuted(){return null!==this._postMuteVolume}setPosition(t){return e(this,void 0,void 0,(function*(){if(t<0||t>100)throw new Error("soundPositionInPercent must be a number >= 0 and <= 100");const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){let i=e.getDuration();(null===i||isNaN(i))&&(yield this._loadSound(e),i=e.getDuration());const o=i/100*t;this.setPositionInSeconds(o)}}))}setPositionInSeconds(i){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){if(!isNaN(e.duration)&&Math.ceil(e.duration),null!==e.onSeeking){const t=i,o=e.getDuration(),n=t/o*100,u=Math.round(n);e.onSeeking(u,o,t)}e.state===t.SOUND_STATE_PLAYING?(e.playTime=i,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?(e.elapsedPlayTime=i,yield this._stop(e,t.SOUND_STATE_SEEKING)):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(e.state=t.SOUND_STATE_SEEKING,yield this._play(e))):(e.playTime=i,e.state=t.SOUND_STATE_SEEKING)}}))}_loadSound(t){return e(this,void 0,void 0,(function*(){switch(this._options.loadPlayerMode){case n.PLAYER_MODE_AUDIO:yield this._loadSoundUsingAudioElement(t);break;case n.PLAYER_MODE_AJAX:yield this._loadSoundUsingRequest(t);case n.PLAYER_MODE_FETCH:}}))}_loadSoundUsingAudioElement(t){return new Promise(((i,o)=>{const{url:n,codec:u=null}=this._findBestSource(t.source);t.url=n,t.codec=u,null!==t.url?this._playerAudio.getAudioElement().then((o=>{t.audioElement=o;const n=()=>e(this,void 0,void 0,(function*(){return t.audioElement.removeEventListener("canplaythrough",n),t.isReadyToPLay=!0,isNaN(t.audioElement.duration)||t.durationSetManually||(t.duration=t.audioElement.duration),i()}));t.audioElement.addEventListener("canplaythrough",n),t.audioElement.onprogress=()=>{if(t.audioElement.buffered.length){const e=t.getDuration(),i=t.audioElement.buffered.end(0),o=100/(e/i),n=Math.round(o);t.loadingProgress=n,null!==t.onLoading&&t.onLoading(n,e,i),t.durationSetManually||(t.duration=t.audioElement.duration),100===n&&(t.isBuffering=!1,t.isBuffered=!0,t.audioBufferDate=new Date)}},t.audioElement.crossOrigin="anonymous",t.audioElement.src=t.url,t.audioElement.load()})).catch(o):o(new Error("sound has no url"))}))}_loadSoundUsingRequest(t){return e(this,void 0,void 0,(function*(){if(null!==t.arrayBuffer)return yield this._decodeSound({sound:t});const{url:e,codec:i=null}=this._findBestSource(t.source);if(t.url=e,t.codec=i,null===t.url)throw new Error("sound has no url");{const e=new o;t.isBuffering=!0;const i=yield e.getArrayBuffer(t);t.arrayBuffer=i,yield this._decodeSound({sound:t})}}))}_decodeSound({sound:t}){return e(this,void 0,void 0,(function*(){const e=t.arrayBuffer.slice(0),i=yield this._playerAudio.decodeAudio(e);t.durationSetManually||(t.duration=i.duration),t.audioBuffer=i,t.isBuffering=!1,t.isBuffered=!0,t.audioBufferDate=new Date,t.isReadyToPLay=!0}))}manuallyUnlockAudio(){return e(this,void 0,void 0,(function*(){yield this._playerAudio.unlockAudio()}))}play({whichSound:i,playTimeOffset:o}={}){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND}),u=this._getSoundFromQueue({whichSound:i,updateIndex:!0});return null===u?u:null!==e&&e.state===t.SOUND_STATE_PLAYING&&e.id===u.id?(isNaN(o)||this.setPositionInSeconds(o),u):(null===e||e.state!==t.SOUND_STATE_PLAYING&&e.state!==t.SOUND_STATE_PAUSED||e.id===u.id||(yield this._stop(e,t.SOUND_STATE_STOPPED)),isNaN(o)?u.playTimeOffset=0:u.playTimeOffset=o,null===u.sourceNode&&(yield this._playerAudio.connectSound(u,(()=>{this._onEnded()}))),u.isReadyToPLay||(yield this._loadSound(u)),yield this._play(u),u)}))}_play(i){return e(this,void 0,void 0,(function*(){this._playerAudio.isAudioContextFrozen()&&(yield this._playerAudio.unfreezeAudioContext()),i.playTimeOffset>0&&(i.playTime=i.playTimeOffset),this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?yield this._playAudioBuffer(i):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(yield this._playMediaElementAudio(i)),i.state=t.SOUND_STATE_PLAYING,this._triggerSoundCallbacks(i)}))}_playAudioBuffer(i){return e(this,void 0,void 0,(function*(){if(i.sourceNode instanceof AudioBufferSourceNode){i.startTime=i.sourceNode.context.currentTime,i.sourceNode.buffer=i.audioBuffer;try{i.state===t.SOUND_STATE_SEEKING||i.state===t.SOUND_STATE_PAUSED&&0===i.playTimeOffset?i.sourceNode.start(0,i.playTime):i.playTimeOffset>0?(i.playTimeOffset,Math.ceil(i.duration),i.elapsedPlayTime=i.playTimeOffset,i.sourceNode.start(0,i.playTimeOffset)):i.sourceNode.start()}catch(e){throw new Error(e)}}}))}_playMediaElementAudio(i){return e(this,void 0,void 0,(function*(){if(i.sourceNode instanceof MediaElementAudioSourceNode)return i.state===t.SOUND_STATE_SEEKING||i.state===t.SOUND_STATE_PAUSED&&0===i.playTimeOffset?i.audioElement.currentTime=i.playTime:i.playTimeOffset>0?(i.playTimeOffset,Math.ceil(i.duration),i.audioElement.currentTime=i.playTimeOffset):i.audioElement.currentTime=0,yield i.audioElement.play()}))}_triggerSoundCallbacks(e){null===e.onResumed||e.firstTimePlayed||e.onResumed(e.playTime),null!==e.onStarted&&e.firstTimePlayed&&(e.firstTimePlayed=!1,e.onStarted(e.playTimeOffset)),null!==e.onPlaying?(this._playingProgressPreviousTimestamp=0,this._progressTrigger(e,0)):this._playingProgressRequestId=null}_onEnded(){return e(this,void 0,void 0,(function*(){if(this._options.playNextOnEnded){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){if(this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO||this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&e.state===t.SOUND_STATE_PLAYING){let t=!1;null!==this._getSoundFromQueue({whichSound:n.PLAY_SOUND_NEXT})&&(t=!0),t||(yield this._playerAudio.freezeAudioContext()),null!==e.onEnded&&e.onEnded(t);try{yield this.next()}catch(e){}}if(this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&e.state===t.SOUND_STATE_SEEKING)try{yield this.play(e)}catch(e){}}}}))}_getSoundFromQueue({whichSound:e,updateIndex:t=!1}={}){let i=null,o=null;if(0===this._queue.length)return i;switch(void 0===e&&(e=n.CURRENT_SOUND),e){case n.CURRENT_SOUND:o=this._currentIndex,i=this._queue[o];break;case n.PLAY_SOUND_NEXT:void 0!==this._queue[this._currentIndex+1]?(o=this._currentIndex+1,i=this._queue[o]):this._options.loopQueue&&(o=0,i=this._queue[o]);break;case n.PLAY_SOUND_PREVIOUS:void 0!==this._queue[this._currentIndex-1]?(o=this._currentIndex-1,i=this._queue[o]):this._options.loopQueue&&(o=this._queue.length-1,i=this._queue[o]);break;case n.PLAY_SOUND_FIRST:this._queue.length>0&&(o=0,i=this._queue[o]);break;case n.PLAY_SOUND_LAST:this._queue.length>0&&(o=this._queue.length-1,i=this._queue[o]);break;default:[i,o]=this._findSoundById({soundId:e})}return null!==o&&t&&(this._currentIndex=o),i}_findSoundById({soundId:e}){let t=null,i=0;return this._queue.some(((o,n)=>{if(o.id===e)return t=o,i=n,!0})),[t,i]}_findBestSource(e){const t={url:null,codec:null};let i;i=Array.isArray(e)?e:[e];let o=0;for(;o<i.length;){const e=i[o];let n="";""!==this._options.soundsBaseUrl&&(n=this._options.soundsBaseUrl),n+=e.url;let u=!0;if(null!==e.codec&&(u=this._checkCodecSupport(e.codec)),u){if(e.isPreferred){t.url=n,t.codec=e.codec;break}t.url=n,t.codec=e.codec}o++}return t}_checkCodecSupport(e){let t,i="";switch(e){case"ogg":case"oga":t=['audio/ogg; codecs="vorbis"'];break;case"mp3":t=['audio/mpeg; codecs="mp3"'];break;case"opus":t=['audio/ogg; codecs="opus"','audio/webm; codecs="opus"'];break;case"wav":t=['audio/wav; codecs="1"'];break;case"m4a":t=["audio/m4a;","audio/x-m4a;"];break;case"m4p":t=["audio/m4p;","audio/x-m4p;"];break;case"caf":t=["audio/x-caf;"];break;case"aac":t=["audio/aac;"];break;case"weba":case"webm":t=['audio/webm; codecs="vorbis"'];break;case"flac":t=["audio/flac;","audio/x-flac;"];break;default:i="unrecognised codec"}if(i)throw new Error(i);return this._checkMimeTypesSupport(t)}_checkMimeTypesSupport(e){const t=new Audio;let i=!1;return e.forEach((e=>{t.canPlayType(e).replace(/^no$/,"")&&(i=!0)})),i}pause(){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null===e)return;if(e.state===t.SOUND_STATE_PAUSED)return;const i=e.getCurrentTime();return e.playTime=i,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&(e.elapsedPlayTime=i),null!==e.onPaused&&e.onPaused(e.playTime),yield this._stop(e,t.SOUND_STATE_PAUSED),e}))}stop(){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e&&e.state!==t.SOUND_STATE_STOPPED)return yield this._playerAudio.freezeAudioContext(),null!==e.onStopped&&e.onStopped(e.playTime),yield this._stop(e,t.SOUND_STATE_STOPPED),e}))}_stop(i,o){return e(this,void 0,void 0,(function*(){null!==this._playingProgressRequestId&&(cancelAnimationFrame(this._playingProgressRequestId),this._playingProgressRequestId=null),i.state=o,null!==i.sourceNode&&(i.sourceNode instanceof AudioBufferSourceNode&&(i.sourceNode.stop(0),yield this._playerAudio.disconnectSound(i)),i.sourceNode instanceof MediaElementAudioSourceNode&&i.audioElement.pause()),o===t.SOUND_STATE_STOPPED&&(i.isReadyToPLay=!1,i.firstTimePlayed=!0,i.startTime=0,i.elapsedPlayTime=0,i.playTime=0,i.playedTimePercentage=0,yield this._playerAudio.disconnectSound(i))}))}next(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_NEXT})}))}previous(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_PREVIOUS})}))}first(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_FIRST})}))}last(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_LAST})}))}setVisibilityAutoMute(e){this._options.visibilityAutoMute=e,e?document.addEventListener("visibilitychange",this._handleVisibilityChange.bind(this),!1):document.removeEventListener("visibilitychange",this._handleVisibilityChange.bind(this),!1)}getVisibilityAutoMute(){return this._options.visibilityAutoMute}_handleVisibilityChange(){let e;void 0!==document.hidden?e="hidden":void 0!==document.msHidden?e="msHidden":void 0!==document.webkitHidden&&(e="webkitHidden"),document[e]?this.mute():this.unMute()}disconnect(){return e(this,void 0,void 0,(function*(){null!==this._playingProgressRequestId&&(cancelAnimationFrame(this._playingProgressRequestId),this._playingProgressRequestId=null),yield this._playerAudio.shutDown(this._queue)}))}getAudioContext(){return e(this,void 0,void 0,(function*(){return yield this._playerAudio.getAudioContext()}))}getCurrentSound(){return this._getSoundFromQueue({whichSound:n.CURRENT_SOUND})}}n.WHERE_IN_QUEUE_AT_END="append",n.WHERE_IN_QUEUE_AT_START="prepend",n.PLAY_SOUND_NEXT="next",n.PLAY_SOUND_PREVIOUS="previous",n.PLAY_SOUND_FIRST="first",n.PLAY_SOUND_LAST="last",n.CURRENT_SOUND="current",n.PLAYER_MODE_AUDIO="player_mode_audio",n.PLAYER_MODE_AJAX="player_mode_ajax",n.PLAYER_MODE_FETCH="player_mode_fetch";export{n as PlayerCore,t as PlayerSound};
function e(e,t,i,o){return new(i||(i=Promise))((function(n,s){function u(e){try{r(o.next(e))}catch(e){s(e)}}function d(e){try{r(o.throw(e))}catch(e){s(e)}}function r(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(u,d)}r((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(e){this.url=null,this.codec=null,this.loop=!1,this.sourceNode=null,this.gainNode=null,this.isReadyToPLay=!1,this.isBuffered=!1,this.isBuffering=!1,this.audioElement=null,this.audioBuffer=null,this.arrayBuffer=null,this.audioBufferDate=null,this.playTimeOffset=0,this.startTime=0,this.elapsedPlayTime=0,this.playTime=0,this.playedTimePercentage=0,this.state="sound_state_stopped",this.loadingProgress=0,this.duration=null,this.durationSetManually=!1,this.firstTimePlayed=!0,this.isConnectToPlayerGain=!1,Array.isArray(e.source)?this.source=e.source:this.source=[e.source],void 0!==e.id?this.id=e.id:this.id=this._generateSoundId(),this.loop=e.loop||!1,isNaN(e.duration)||(this.duration=e.duration,this.durationSetManually=!0),"function"==typeof e.onLoading?this.onLoading=e.onLoading:this.onLoading=null,"function"==typeof e.onPlaying?this.onPlaying=e.onPlaying:this.onPlaying=null,"function"==typeof e.onStarted?this.onStarted=e.onStarted:this.onStarted=null,"function"==typeof e.onEnded?this.onEnded=e.onEnded:this.onEnded=null,"function"==typeof e.onStopped?this.onStopped=e.onStopped:this.onStopped=null,"function"==typeof e.onPaused?this.onPaused=e.onPaused:this.onPaused=null,"function"==typeof e.onResumed?this.onResumed=e.onResumed:this.onResumed=null,"function"==typeof e.onSeeking?this.onSeeking=e.onSeeking:this.onSeeking=null,e.arrayBuffer instanceof ArrayBuffer&&(this.arrayBuffer=e.arrayBuffer),e.audioBuffer instanceof AudioBuffer&&(this.audioBuffer=e.audioBuffer,this.isBuffering=!1,this.isBuffered=!0,this.audioBufferDate=new Date,this.durationSetManually||(this.duration=this.audioBuffer.duration))}getCurrentTime(){let e;return null!==this.sourceNode&&(this.sourceNode instanceof AudioBufferSourceNode?e=this.sourceNode.context.currentTime-this.startTime+this.elapsedPlayTime:this.sourceNode instanceof MediaElementAudioSourceNode&&(e=this.audioElement.currentTime)),e}getDuration(){let e;return null!==this.sourceNode&&(this.sourceNode instanceof AudioBufferSourceNode?e=this.audioBuffer.duration:this.sourceNode instanceof MediaElementAudioSourceNode&&(e=this.audioElement.duration)),e}setDuration(e){isNaN(e)||(this.duration=e,this.durationSetManually=!0)}setLoop(e){this.loop=e,this.state===t.SOUND_STATE_PLAYING&&null!==this.sourceNode&&(this.sourceNode instanceof AudioBufferSourceNode?this.sourceNode.loop=e:this.sourceNode instanceof MediaElementAudioSourceNode&&(this.sourceNode.mediaElement.loop=e))}getLoop(){return this.loop}_generateSoundId(){return Date.now().toString(36)+Math.random().toString(36).substring(2)}}t.SOUND_STATE_STOPPED="sound_state_stopped",t.SOUND_STATE_PAUSED="sound_state_paused",t.SOUND_STATE_PLAYING="sound_state_playing",t.SOUND_STATE_SEEKING="sound_state_seeking";class i{constructor(e){this._audioContext=null,this._volume=null,this._audioNodes={gainNode:null},this._audioElement=null,this._mediaElementAudioSourceNode=null,this._isAudioUnlocked=!1,this._isAudioUnlocking=!1,this._options=e,this._initialize()}_initialize(){this._options.unlockAudioOnFirstUserInteraction&&this._addFirstUserInteractionEventListeners()}getAudioNodes(){return this._audioNodes}decodeAudio(t){return e(this,void 0,void 0,(function*(){const e=yield this.getAudioContext();return yield e.decodeAudioData(t)}))}_createAudioContext(){if(this._audioContext instanceof AudioContext)return;const e=window.AudioContext||window.webkitAudioContext;null!==this._options.audioContext?this._audioContext=this._options.audioContext:this._audioContext=new e}_addFirstUserInteractionEventListeners(){this._options.unlockAudioOnFirstUserInteraction&&(document.addEventListener("keydown",this.unlockAudio.bind(this)),document.addEventListener("mousedown",this.unlockAudio.bind(this)),document.addEventListener("pointerdown",this.unlockAudio.bind(this)),document.addEventListener("pointerup",this.unlockAudio.bind(this)),document.addEventListener("touchend",this.unlockAudio.bind(this)))}_removeFirstUserInteractionEventListeners(){this._options.unlockAudioOnFirstUserInteraction&&(document.removeEventListener("keydown",this.unlockAudio.bind(this)),document.removeEventListener("mousedown",this.unlockAudio.bind(this)),document.removeEventListener("pointerdown",this.unlockAudio.bind(this)),document.removeEventListener("pointerup",this.unlockAudio.bind(this)),document.removeEventListener("touchend",this.unlockAudio.bind(this)))}unlockAudio(){return new Promise(((e,t)=>{if(this._isAudioUnlocking)return e();if(this._isAudioUnlocked)return e();if(this._isAudioUnlocking=!0,"player_mode_audio"===this._options.loadPlayerMode){const e=!0;this._createAudioElement(e).catch((e=>(this._isAudioUnlocking=!1,t())))}this.getAudioContext().then((()=>{const t=this._audioContext.createBuffer(1,1,22050);let i=this._audioContext.createBufferSource();i.onended=()=>(i.disconnect(0),this._removeFirstUserInteractionEventListeners(),i.disconnect(0),i.buffer=null,i=null,this._isAudioUnlocked=!0,this._isAudioUnlocking=!1,e()),i.buffer=t,i.connect(this._audioContext.destination),i.start(0)})).catch((e=>(this._isAudioUnlocking=!1,t())))}))}_createAudioElementAndSource(){return e(this,void 0,void 0,(function*(){yield this._createAudioElement(),yield this._createMediaElementAudioSourceNode()}))}_createAudioElement(t){return e(this,void 0,void 0,(function*(){if(null===this._audioElement||!0===t){const e=new Audio;e.controls=!1,e.autoplay=!1,e.preload="auto",e.volume=1,e.id="web-audio-api-player",this._audioElement=e,this._options.addAudioElementsToDom&&document.body.appendChild(e)}}))}getAudioElement(){return e(this,void 0,void 0,(function*(){return null===this._audioElement&&(yield this._createAudioElementAndSource()),this._audioElement}))}getAudioContext(){return e(this,void 0,void 0,(function*(){return null===this._audioContext||"closed"===this._audioContext.state?yield this._createAudioContext():"suspended"===this._audioContext.state&&(yield this.unfreezeAudioContext()),this._audioContext}))}unfreezeAudioContext(){return void 0===this._audioContext.resume?Promise.resolve():this._audioContext.resume()}freezeAudioContext(){return void 0===this._audioContext.suspend?Promise.resolve():this._audioContext.suspend()}isAudioContextFrozen(){return"suspended"===this._audioContext.state}detectAudioContextSupport(){let e=!1;return(void 0!==window.webkitAudioContext||"undefined"!=typeof AudioContext)&&(e=!0),e}detectAudioElementSupport(){return!!document.createElement("audio").canPlayType}_createAudioBufferSourceNode(){return e(this,void 0,void 0,(function*(){return(yield this.getAudioContext()).createBufferSource()}))}_createMediaElementAudioSourceNode(){return e(this,void 0,void 0,(function*(){if(null===this._mediaElementAudioSourceNode&&null!==this._audioElement){const e=yield this.getAudioContext();this._mediaElementAudioSourceNode=e.createMediaElementSource(this._audioElement)}}))}_destroyMediaElementAudioSourceNode(){null!==this._mediaElementAudioSourceNode&&(void 0!==this._mediaElementAudioSourceNode.mediaElement&&this._mediaElementAudioSourceNode.mediaElement.remove(),this._mediaElementAudioSourceNode.disconnect(),this._mediaElementAudioSourceNode=null)}_destroyAudioBufferSourceNode(){null!==this._mediaElementAudioSourceNode&&this._mediaElementAudioSourceNode.disconnect()}_destroyAudioContext(){return e(this,void 0,void 0,(function*(){null!==this._audioContext&&"closed"!==this._audioContext.state&&(yield this._audioContext.close(),this._audioContext=null)}))}shutDown(t){return e(this,void 0,void 0,(function*(){this._removeFirstUserInteractionEventListeners(),t.forEach((e=>{this.disconnectSound(e)})),this._destroyMediaElementAudioSourceNode(),this._destroyAudioBufferSourceNode(),this._disconnectPlayerGainNode(),yield this._destroyAudioContext()}))}_getPlayerGainNode(){return e(this,void 0,void 0,(function*(){let e;if(this._audioNodes.gainNode instanceof GainNode)e=this._audioNodes.gainNode;else{const t=yield this.getAudioContext();e=t.createGain(),this._initializeVolume(e),e.connect(t.destination),this._audioNodes.gainNode=e}return e}))}_disconnectPlayerGainNode(){null!==this._audioNodes.gainNode&&(this._audioNodes.gainNode.disconnect(),this._audioNodes.gainNode=null)}connectSound(t,i){return e(this,void 0,void 0,(function*(){if(t.isConnectToPlayerGain)return;if("player_mode_ajax"===this._options.loadPlayerMode){const e=yield this._createAudioBufferSourceNode();t.gainNode=e.context.createGain(),e.connect(t.gainNode),e.loop=t.loop,e.onended=i,t.sourceNode=e}else"player_mode_audio"===this._options.loadPlayerMode&&(yield this._createAudioElementAndSource(),t.gainNode=this._mediaElementAudioSourceNode.context.createGain(),this._mediaElementAudioSourceNode.connect(t.gainNode),this._mediaElementAudioSourceNode.mediaElement.loop=t.loop,this._mediaElementAudioSourceNode.mediaElement.onended=i,t.sourceNode=this._mediaElementAudioSourceNode);t.gainNode.gain.value=1;const e=yield this._getPlayerGainNode();t.gainNode.connect(e),t.isConnectToPlayerGain=!0}))}disconnectSound(t){return e(this,void 0,void 0,(function*(){t.isConnectToPlayerGain&&(null!==t.sourceNode&&(t.sourceNode.disconnect(),t.sourceNode=null),null!==t.gainNode&&(t.gainNode.disconnect(),t.gainNode=null,t.isConnectToPlayerGain=!1),null!==t.audioElement&&(t.audioElement=null))}))}_changePlayerGainValue(t){return e(this,void 0,void 0,(function*(){if(this._audioNodes.gainNode instanceof GainNode){const e=yield this.getAudioContext(),i=(!isNaN(this._options.volumeTransitionTime)&&this._options.volumeTransitionTime>0?this._options.volumeTransitionTime:100)/1e3;try{this._audioNodes.gainNode.gain.setTargetAtTime(t,e.currentTime,i)}catch(e){}}}))}setVolume(t,i=!0){return e(this,void 0,void 0,(function*(){this._options.persistVolume&&i&&localStorage.setItem("WebAudioAPIPlayerVolume",t.toString());const e=t/100;if(this._audioNodes.gainNode instanceof GainNode){e!==Math.round(100*(this._audioNodes.gainNode.gain.value+Number.EPSILON))/100&&(yield this._changePlayerGainValue(e))}return this._volume=t,t}))}getVolume(){let e;if(null!==this._volume)e=this._volume;else if(this._options.persistVolume){e=parseInt(localStorage.getItem("WebAudioAPIPlayerVolume"))}return(void 0===e||isNaN(e))&&(e=isNaN(this._options.volume)?80:this._options.volume),this._volume=e,e}_initializeVolume(e){if(this._options.persistVolume){const t=parseInt(localStorage.getItem("WebAudioAPIPlayerVolume")),i=t/100;isNaN(t)||(e.gain.value=i),this._volume=t}if(null===this._volume){const t=this._options.volume/100;e.gain.value=t,this._volume=this._options.volume}}}class o{getArrayBuffer(e){return new Promise((function(t,i){const o=new XMLHttpRequest;o.open("GET",e.url,!0),o.responseType="arraybuffer",o.onload=function(){o.status>=200&&o.status<=299?t(o.response):i(new Error(o.statusText+"(status:"+o.status+")"))},o.onprogress=function(t){const i=100/(t.total/t.loaded),o=Math.round(i);e.loadingProgress=o,null!==e.onLoading&&e.onLoading(o,t.total,t.loaded)},o.onerror=function(e){i(e)},o.send()}))}}class n{constructor(e={}){this._playingProgressRequestId=null,this._postMuteVolume=null,this._progressTrigger=(e,i)=>{const o=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(e.id===o.id&&o.state===t.SOUND_STATE_PLAYING){if(i-this._playingProgressPreviousTimestamp>=this._options.playingProgressIntervalTime){const t=e.getCurrentTime(),o=e.getDuration();if(!isNaN(t)&&!isNaN(o)){let n=0;if(0!==t){const e=t/o*100;n=Math.round(e)}e.playedTimePercentage=n,e.playTime=t,e.onPlaying(n,o,t),this._playingProgressPreviousTimestamp=i}}this._playingProgressRequestId=window.requestAnimationFrame((t=>{this._progressTrigger(e,t)}))}};const i={volume:80,loopQueue:!1,loopSong:!1,soundsBaseUrl:"",playingProgressIntervalTime:200,playNextOnEnded:!0,stopOnReset:!0,visibilityAutoMute:!1,unlockAudioOnFirstUserInteraction:!1,persistVolume:!0,loadPlayerMode:"player_mode_audio",audioContext:null,addAudioElementsToDom:!1,volumeTransitionTime:100},o=Object.assign({},i,e);this._queue=[],this._currentIndex=0,this._options=o,this._playingProgressPreviousTimestamp=0,this._initialize()}_initialize(){const e=this._audioOptions();switch(this._playerAudio=new i(e),this._options.loadPlayerMode){case n.PLAYER_MODE_AUDIO:if(!this._playerAudio.detectAudioContextSupport())throw new Error("audio context is not supported by this device");if(!this._playerAudio.detectAudioElementSupport())throw new Error("audio element is not supported by this device");break;case n.PLAYER_MODE_AJAX:if(!this._playerAudio.detectAudioContextSupport())throw new Error("audio context is not supported by this device")}}_audioOptions(){return{audioContext:this._options.audioContext,unlockAudioOnFirstUserInteraction:this._options.unlockAudioOnFirstUserInteraction,volume:this._options.volume,persistVolume:this._options.persistVolume,loadPlayerMode:this._options.loadPlayerMode,addAudioElementsToDom:this._options.addAudioElementsToDom,volumeTransitionTime:this._options.volumeTransitionTime}}addSoundToQueue({soundAttributes:e,whereInQueue:i="append"}){const o=new t(e);switch(i){case n.WHERE_IN_QUEUE_AT_END:this._appendSoundToQueue(o);break;case n.WHERE_IN_QUEUE_AT_START:this._prependSoundToQueue(o)}return o}_appendSoundToQueue(e){this._queue.push(e)}_prependSoundToQueue(e){this._queue.unshift(e)}resetQueue(){return e(this,void 0,void 0,(function*(){this._options.stopOnReset&&(yield this.stop()),this._queue.forEach((e=>{this._playerAudio.disconnectSound(e)})),this._queue=[]}))}reset(){this.resetQueue().catch((e=>{}))}getQueue(){return this._queue}setVolume(e){this._playerAudio.setVolume(e).catch((e=>{}))}getVolume(){return this._playerAudio.getVolume()}setLoopQueue(e){this._options.loopQueue=e}getLoopQueue(){return this._options.loopQueue}mute(){const e=this.getVolume();this._playerAudio.setVolume(0,!1).catch((e=>{})),this._postMuteVolume=e}unMute(){this._playerAudio.setVolume(this._postMuteVolume,!1).catch((e=>{})),this._postMuteVolume=null}isMuted(){return null!==this._postMuteVolume}setPosition(t){return e(this,void 0,void 0,(function*(){if(t<0||t>100)throw new Error("soundPositionInPercent must be a number >= 0 and <= 100");const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){let i=e.getDuration();(null===i||isNaN(i))&&(yield this._loadSound(e),i=e.getDuration());const o=i/100*t;this.setPositionInSeconds(o)}}))}setPositionInSeconds(i){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){if(!isNaN(e.duration)&&i>=e.duration&&(i=e.duration-.1),null!==e.onSeeking){const t=i,o=e.getDuration(),n=t/o*100,s=Math.round(n);e.onSeeking(s,o,t)}e.state===t.SOUND_STATE_PLAYING?(e.playTime=i,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?(e.elapsedPlayTime=i,yield this._stop(e,t.SOUND_STATE_SEEKING)):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(e.state=t.SOUND_STATE_SEEKING,yield this._play(e))):(e.playTime=i,e.state=t.SOUND_STATE_SEEKING)}}))}_loadSound(t){return e(this,void 0,void 0,(function*(){switch(this._options.loadPlayerMode){case n.PLAYER_MODE_AUDIO:yield this._loadSoundUsingAudioElement(t);break;case n.PLAYER_MODE_AJAX:yield this._loadSoundUsingRequest(t);case n.PLAYER_MODE_FETCH:}}))}_loadSoundUsingAudioElement(t){return e(this,void 0,void 0,(function*(){const{url:i,codec:o=null}=this._findBestSource(t.source);if(t.url=i,t.codec=o,null===t.url)throw new Error("sound has no url");{t.audioElement=yield this._playerAudio.getAudioElement(),t.audioElement.onprogress=()=>{if(t.audioElement.buffered.length){const e=t.getDuration(),i=t.audioElement.buffered.end(0),o=100/(e/i),n=Math.round(o);t.loadingProgress=n,null!==t.onLoading&&t.onLoading(n,e,i),100===n&&(t.isBuffering=!1,t.isBuffered=!0,t.audioBufferDate=new Date)}};const i=()=>e(this,void 0,void 0,(function*(){t.audioElement.removeEventListener("canplaythrough",i),t.isReadyToPLay=!0,isNaN(t.audioElement.duration)||t.durationSetManually||(t.duration=t.audioElement.duration),yield this._play(t)}));t.audioElement.addEventListener("canplaythrough",i),t.audioElement.crossOrigin="anonymous",t.audioElement.src=t.url,t.audioElement.load()}}))}_loadSoundUsingRequest(t){return e(this,void 0,void 0,(function*(){if(null!==t.arrayBuffer)return yield this._decodeSound({sound:t});const{url:e,codec:i=null}=this._findBestSource(t.source);if(t.url=e,t.codec=i,null===t.url)throw new Error("sound has no url");{const e=new o;t.isBuffering=!0;const i=yield e.getArrayBuffer(t);t.arrayBuffer=i,yield this._decodeSound({sound:t})}}))}_decodeSound({sound:t}){return e(this,void 0,void 0,(function*(){const e=t.arrayBuffer.slice(0),i=yield this._playerAudio.decodeAudio(e);t.durationSetManually||(t.duration=i.duration),t.audioBuffer=i,t.isBuffering=!1,t.isBuffered=!0,t.audioBufferDate=new Date,t.isReadyToPLay=!0,yield this._play(t)}))}play({whichSound:i,playTimeOffset:o}={}){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND}),s=this._getSoundFromQueue({whichSound:i,updateIndex:!0});return null===s?s:null!==e&&e.state===t.SOUND_STATE_PLAYING&&e.id===s.id?(isNaN(o)||this.setPositionInSeconds(o),s):(null===e||e.state!==t.SOUND_STATE_PLAYING&&e.state!==t.SOUND_STATE_PAUSED||e.id===s.id||(yield this._stop(e,t.SOUND_STATE_STOPPED)),isNaN(o)?s.playTimeOffset=0:s.playTimeOffset=o,null===s.sourceNode&&(yield this._playerAudio.connectSound(s,(()=>{this._onEnded()}))),s.isReadyToPLay?yield this._play(s):yield this._loadSound(s),s)}))}_play(i){return e(this,void 0,void 0,(function*(){i.state!==t.SOUND_STATE_PLAYING&&(this._playerAudio.isAudioContextFrozen()&&(yield this._playerAudio.unfreezeAudioContext()),i.playTimeOffset>0&&(i.playTime=i.playTimeOffset),this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?yield this._playAudioBuffer(i):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(yield this._playMediaElementAudio(i)),i.state=t.SOUND_STATE_PLAYING,this._triggerSoundCallbacks(i))}))}_playAudioBuffer(i){return e(this,void 0,void 0,(function*(){if(i.sourceNode instanceof AudioBufferSourceNode){i.startTime=i.sourceNode.context.currentTime,i.sourceNode.buffer=i.audioBuffer;try{i.state===t.SOUND_STATE_SEEKING||i.state===t.SOUND_STATE_PAUSED&&0===i.playTimeOffset?i.sourceNode.start(0,i.playTime):i.playTimeOffset>0?(i.playTimeOffset,Math.ceil(i.duration),i.elapsedPlayTime=i.playTimeOffset,i.sourceNode.start(0,i.playTimeOffset)):i.sourceNode.start()}catch(e){throw new Error(e)}}}))}_playMediaElementAudio(i){return e(this,void 0,void 0,(function*(){if(i.sourceNode instanceof MediaElementAudioSourceNode)return i.state===t.SOUND_STATE_SEEKING||i.state===t.SOUND_STATE_PAUSED&&0===i.playTimeOffset?i.audioElement.currentTime=i.playTime:i.playTimeOffset>0?(i.playTimeOffset,Math.ceil(i.duration),i.audioElement.currentTime=i.playTimeOffset):i.audioElement.currentTime=0,yield i.audioElement.play()}))}_triggerSoundCallbacks(e){null===e.onResumed||e.firstTimePlayed||e.onResumed(e.playTime),null!==e.onStarted&&e.firstTimePlayed&&(e.firstTimePlayed=!1,e.onStarted(e.playTimeOffset)),null!==e.onPlaying?(this._playingProgressPreviousTimestamp=0,this._progressTrigger(e,0)):this._playingProgressRequestId=null}_onEnded(){return e(this,void 0,void 0,(function*(){if(this._options.playNextOnEnded){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){if(this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO||this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&e.state===t.SOUND_STATE_PLAYING){let t=!1;null!==this._getSoundFromQueue({whichSound:n.PLAY_SOUND_NEXT})&&(t=!0),t||(yield this._playerAudio.freezeAudioContext()),null!==e.onEnded&&e.onEnded(t);try{t&&(yield this.next())}catch(e){}}if(this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&e.state===t.SOUND_STATE_SEEKING)try{yield this.play(e)}catch(e){}}}}))}_getSoundFromQueue({whichSound:e,updateIndex:t=!1}={}){let i=null,o=null;if(0===this._queue.length)return i;switch(void 0===e&&(e=n.CURRENT_SOUND),e){case n.CURRENT_SOUND:o=this._currentIndex,i=this._queue[o];break;case n.PLAY_SOUND_NEXT:void 0!==this._queue[this._currentIndex+1]?(o=this._currentIndex+1,i=this._queue[o]):this._options.loopQueue&&(o=0,i=this._queue[o]);break;case n.PLAY_SOUND_PREVIOUS:void 0!==this._queue[this._currentIndex-1]?(o=this._currentIndex-1,i=this._queue[o]):this._options.loopQueue&&(o=this._queue.length-1,i=this._queue[o]);break;case n.PLAY_SOUND_FIRST:this._queue.length>0&&(o=0,i=this._queue[o]);break;case n.PLAY_SOUND_LAST:this._queue.length>0&&(o=this._queue.length-1,i=this._queue[o]);break;default:[i,o]=this._findSoundById({soundId:e})}return null!==o&&t&&(this._currentIndex=o),i}_findSoundById({soundId:e}){let t=null,i=0;return this._queue.some(((o,n)=>{if(o.id===e)return t=o,i=n,!0})),[t,i]}_findBestSource(e){const t={url:null,codec:null};let i;i=Array.isArray(e)?e:[e];let o=0;for(;o<i.length;){const e=i[o];let n="";""!==this._options.soundsBaseUrl&&(n=this._options.soundsBaseUrl),n+=e.url;let s=!0;if(null!==e.codec&&(s=this._checkCodecSupport(e.codec)),s){if(e.isPreferred){t.url=n,t.codec=e.codec;break}t.url=n,t.codec=e.codec}o++}return t}_checkCodecSupport(e){let t,i="";switch(e){case"ogg":case"oga":t=['audio/ogg; codecs="vorbis"'];break;case"mp3":t=['audio/mpeg; codecs="mp3"'];break;case"opus":t=['audio/ogg; codecs="opus"','audio/webm; codecs="opus"'];break;case"wav":t=['audio/wav; codecs="1"'];break;case"m4a":t=["audio/m4a;","audio/x-m4a;"];break;case"m4p":t=["audio/m4p;","audio/x-m4p;"];break;case"caf":t=["audio/x-caf;"];break;case"aac":t=["audio/aac;"];break;case"weba":case"webm":t=['audio/webm; codecs="vorbis"'];break;case"flac":t=["audio/flac;","audio/x-flac;"];break;default:i="unrecognised codec"}if(i)throw new Error(i);return this._checkMimeTypesSupport(t)}_checkMimeTypesSupport(e){const t=new Audio;let i=!1;return e.forEach((e=>{t.canPlayType(e).replace(/^no$/,"")&&(i=!0)})),i}pause(){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null===e)return;if(e.state===t.SOUND_STATE_PAUSED)return;const i=e.getCurrentTime();return e.playTime=i,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&(e.elapsedPlayTime=i),null!==e.onPaused&&e.onPaused(e.playTime),yield this._stop(e,t.SOUND_STATE_PAUSED),e}))}stop(){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e&&e.state!==t.SOUND_STATE_STOPPED)return yield this._playerAudio.freezeAudioContext(),null!==e.onStopped&&e.onStopped(e.playTime),yield this._stop(e,t.SOUND_STATE_STOPPED),e}))}_stop(i,o){return e(this,void 0,void 0,(function*(){null!==this._playingProgressRequestId&&(cancelAnimationFrame(this._playingProgressRequestId),this._playingProgressRequestId=null),i.state=o,null!==i.sourceNode&&(i.sourceNode instanceof AudioBufferSourceNode&&(i.sourceNode.stop(0),yield this._playerAudio.disconnectSound(i)),i.sourceNode instanceof MediaElementAudioSourceNode&&i.audioElement.pause()),o===t.SOUND_STATE_STOPPED&&(i.isReadyToPLay=!1,i.firstTimePlayed=!0,i.startTime=0,i.elapsedPlayTime=0,i.playTime=0,i.playedTimePercentage=0,yield this._playerAudio.disconnectSound(i))}))}next(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_NEXT})}))}previous(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_PREVIOUS})}))}first(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_FIRST})}))}last(){return e(this,void 0,void 0,(function*(){return yield this.play({whichSound:n.PLAY_SOUND_LAST})}))}setVisibilityAutoMute(e){this._options.visibilityAutoMute=e,e?document.addEventListener("visibilitychange",this._handleVisibilityChange.bind(this),!1):document.removeEventListener("visibilitychange",this._handleVisibilityChange.bind(this),!1)}getVisibilityAutoMute(){return this._options.visibilityAutoMute}_handleVisibilityChange(){let e;void 0!==document.hidden?e="hidden":void 0!==document.msHidden?e="msHidden":void 0!==document.webkitHidden&&(e="webkitHidden"),document[e]?this.mute():this.unMute()}manuallyUnlockAudio(){return e(this,void 0,void 0,(function*(){yield this._playerAudio.unlockAudio()}))}disconnect(){return e(this,void 0,void 0,(function*(){null!==this._playingProgressRequestId&&(cancelAnimationFrame(this._playingProgressRequestId),this._playingProgressRequestId=null),yield this._playerAudio.shutDown(this._queue)}))}getAudioContext(){return e(this,void 0,void 0,(function*(){return yield this._playerAudio.getAudioContext()}))}getCurrentSound(){return this._getSoundFromQueue({whichSound:n.CURRENT_SOUND})}}n.WHERE_IN_QUEUE_AT_END="append",n.WHERE_IN_QUEUE_AT_START="prepend",n.PLAY_SOUND_NEXT="next",n.PLAY_SOUND_PREVIOUS="previous",n.PLAY_SOUND_FIRST="first",n.PLAY_SOUND_LAST="last",n.CURRENT_SOUND="current",n.PLAYER_MODE_AUDIO="player_mode_audio",n.PLAYER_MODE_AJAX="player_mode_ajax",n.PLAYER_MODE_FETCH="player_mode_fetch";export{n as PlayerCore,t as PlayerSound};
//# sourceMappingURL=index.min.js.map

@@ -88,3 +88,2 @@ import { ISound, ISoundAttributes, ISoundSource, typeSoundStates } from './sound';

protected _decodeSound({ sound }: IDecodeSoundOptions): Promise<void>;
manuallyUnlockAudio(): Promise<void>;
play({ whichSound, playTimeOffset }?: IPlayOptions): Promise<ISound>;

@@ -112,2 +111,3 @@ protected _play(sound: ISound): Promise<void>;

protected _handleVisibilityChange(): void;
manuallyUnlockAudio(): Promise<void>;
disconnect(): Promise<void>;

@@ -114,0 +114,0 @@ getAudioContext(): Promise<AudioContext>;

{
"name": "web-audio-api-player",
"version": "5.1.0",
"version": "5.1.1",
"description": "web audio api player",

@@ -5,0 +5,0 @@ "keywords": [

@@ -11,8 +11,14 @@ [![npm version](https://img.shields.io/npm/v/web-audio-api-player.svg?style=flat)](https://www.npmjs.com/package/web-audio-api-player)

🎶 An opensource javascript (typescript) audio player for the browser, built using the Web Audio API with support for HTML5 audio elements
🎶 An opensource javascript (typescript) audio player for the browser, built using the Web Audio API with support for HTML5 audio elements
this player can be added to any javascript project and extended in many ways, it is not bound to a specific UI, this player is just a core that can be used to create any kind of player you can imagine and even be used to play sound in video games or for any other sound / song playing needs you may have
This player can be added to any javascript project and extended in many ways, it is not bound to a specific UI, this player is just a core that can be used to create any kind of player you can imagine
Want to help improve the documentation or contribute to this project by improving and fixing it, then first check out the [TODOs section](#todos-ideas-for-future-improvements) below, maybe there is something in the list you want to help with. Any contribution, even things not listed on the TODO list are of course welcome. To get started check out the section ["contributing" section](#contributing-prs-welcome) below.
To get started I recommend checking out the [guide to building a simple audio player UI](#guide-to-building-a-simple-audio-player-ui) in this readme, or head straight to the [player options](#player-options) and functions documentation, but also have a look at the code of the working [simple player example](examples/simple-player) that is part of this repository
If you want to help improve the documentation or contribute to this project by improving and fixing it, then first check out the [TODOs section](#todos-ideas-for-future-improvements) below, maybe there is something in the list you want to help with
Any contribution, even things not listed on the TODO list are of course welcome. To get started check out the section ["contributing" section](#contributing-prs-welcome) below
If you found a bug or want to request a new feature please go to the [issues page](https://github.com/chrisweb/web-audio-api-player/issues) and if you have a question please use the [dicussions page](https://github.com/chrisweb/web-audio-api-player/discussions)
## installation

@@ -228,3 +234,3 @@

* persistVolume: [boolean] (default: true) if this value is set to true the player will use the localstorage of the browser and save the value of the volume (localstorage entry key is **WebAudioAPIPlayerVolume**), if the page gets reloaded or the user comes back later the player will check if there is a value in the localstorage and automatically set the player volume to that value
* loadPlayerMode: [typePlayerModes] (default: PLAYER_MODE_AUDIO) this is a constant you can import from player, currently you can chose between two modes, [PLAYER_MODE_AUDIO](#player_mode_audio) which uses the audio element to load sounds via the audio element and [PLAYER_MODE_AJAX](#player_mode_ajax) to load sounds via the web audio API, for more info about the modes read the [modes extended knowledge](#modes-extended-knowledge) chapter
* loadPlayerMode: [typePlayerModes] (default: PLAYER_MODE_AUDIO) this is a constant you can import from player, currently you can choose between two modes, [PLAYER_MODE_AUDIO](#player-modes-explained) which uses the audio element to load sounds via the audio element and [PLAYER_MODE_AJAX](#player-modes-explained) to load sounds via the web audio API, for more info about the modes read the [player modes explained](#player-modes-explained) chapter
* audioContext: [AudioContext] (default: null) a custom [audiocontext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) you inject to replace the default audiocontext of the player

@@ -324,3 +330,3 @@ * addAudioElementsToDom: [boolean] (default: false) when audio elements get created, they are by default offscreen (not added to the DOM), if you want the audio elements to be added to the DOM set this option to true

* arrayBuffer: [ArrayBuffer] (optional) if you want to inject your own custom [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) to be used instead of the default one the player will create
* duration: [number] (optional) if you know the duration of the sound and want to tell the player about it early, in [PLAYER_MODE_AJAX](#player_mode_ajax) the player will need to wait for the sound to be fully loaded until it can determine the duration
* duration: [number] (optional) if you know the duration of the sound and want to tell the player about it early, in [PLAYER_MODE_AJAX](#player-modes-explained) the player will need to wait for the sound to be fully loaded until it can determine the duration

@@ -330,4 +336,4 @@ **sound callbacks:**

* onLoading(loadingPercentage, total, loaded): [function] (optional) a callback function that will get triggered at intervals during the loading process of a sound, the interval duration can be changed using the [player option "playingProgressIntervalTime"](#player-options), the callback has three parameters, **loadingPercentage** is the percentage that has been loaded so far (number ranging from 0 to 100)
* if the player mode is [PLAYER_MODE_AUDIO](#player_mode_audio), then **total** is an integer telling you the total song duration in seconds ([MDN HTMLMediaElement duration](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration)), **loaded** is an integer that tells you the amount that already got loaded (buffered end) in seconds ([MDN HTMLMediaElement timerange end](https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges/end)), if you prefer to use the raw values I recommend you use the **sound.audioElement.buffered** and read them periodically yourself
* if the player mode is [PLAYER_MODE_AJAX](#player_mode_ajax), then **total** is an integer telling you the total bytes that will get loaded ([MDN ProgressEvent total](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/total)), **loaded** is an integer that tells you the amount of bytes that already got loaded ([MDN ProgressEvent loaded](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/loaded))
* if the player mode is [PLAYER_MODE_AUDIO](#player-modes-explained), then **total** is an integer telling you the total song duration in seconds ([MDN HTMLMediaElement duration](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration)), **loaded** is an integer that tells you the amount that already got loaded (buffered end) in seconds ([MDN HTMLMediaElement timerange end](https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges/end)), if you prefer to use the raw values I recommend you use the **sound.audioElement.buffered** and read them periodically yourself
* if the player mode is [PLAYER_MODE_AJAX](#player-modes-explained), then **total** is an integer telling you the total bytes that will get loaded ([MDN ProgressEvent total](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/total)), **loaded** is an integer that tells you the amount of bytes that already got loaded ([MDN ProgressEvent loaded](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/loaded))
* onPlaying(playingPercentage, duration, playTime)): [function] (optional) a callback function that will get triggered at intervals while the sound is playing, the callback has three parameters, **playingPercentage** is the percentage that has been played so far (number ranging from 0 to 100), **duration** is the total song duration, playTime is the current time in seconds that have been played

@@ -368,26 +374,18 @@ * onEnded(willPlayNext): [function] (optional) a callback function that will get triggered when the end of the sound is reached, returns one parameter **willPlayNext** which is a boolean, true if there is a next song in the internal queue that will get played or false if no next sound will get played

### modes extended knowledge
### player modes explained
#### player modes differences clarification
Note: You might have read (like I did) a lot of outdated web audio articles which stated the web audio element lacks a lot of features the web audio API and that hence it is not suited to create complex audio software or for example be used in games where you might want to add effects and filters to sounds. This is not true anymore and especially not true for this library. Yes the audio element if used as a standalone lacks a lot of features. But this library does combine the web audio element with the web audio API, meaning that no matter what mode you chose the sound will be converted to an AudioSourceNode.
If you use this library, the difference is only how the sound (song) gets loaded:
If you use this library, you have two player modes you can chose to use, the main difference is how the sound (song) gets loaded:
##### PLAYER_MODE_AJAX
**PLAYER_MODE_AJAX** will use an [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) the source will be an [AudioBufferSourceNode](https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode)
will use an [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) the source will be an [AudioBufferSourceNode](https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode)
**PLAYER_MODE_AUDIO** will use the HTML [audio element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio), then the player will use [createMediaElementSource](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createMediaElementSource) method of the [AudioContext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) internally to create an [MediaElementAudioSourceNode](https://developer.mozilla.org/en-US/docs/Web/API/MediaElementAudioSourceNode)
##### PLAYER_MODE_AUDIO
will use the HTML [audio element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio), then the player will use [createMediaElementSource](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createMediaElementSource) method of the [AudioContext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) internally to create an [MediaElementAudioSourceNode](https://developer.mozilla.org/en-US/docs/Web/API/MediaElementAudioSourceNode)
#### so which PLAYER_MODE should I use
It depends on what you intend to build.
If you build something like a music player, it is probably best to use the PLAYER_MODE_AUDIO as you might want to start playing the sound (song) as quickly as possible and don't care if it has fully loaded. This mode is ideal for big files that don't get loaded all at once (streaming). The audio mode (via the audio element) has support for partial content (http code 206) this means with this mode the song will start playing as soon as enough data has been buffered even though the song has not been fully loaded yet (it will load more data from the server in the background as the song progresses). The loading progress callback will return a percentage, which represents the amount of data that got loaded so far, which means it might not represent the loading state of the full song. If you want to display what parts of the song have been loaded more accurately (display the time range(s) that got loaded) I recommend using a [2D canvas element](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) and to get the ranges that have been loaded, I recommend you use the **audioElement** property of a song to get the song.audioElement that is loading the song and then read the [audioElement.buffered](https://developer.mozilla.org/en-US/docs/Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges) value(s).
If you build something like a music player, it is probably best to use the PLAYER_MODE_AUDIO as you might want to start playing the sound (song) as quickly as possible and don't care if it has fully loaded. This mode is ideal for big files that don't get loaded all at once (streaming). The audio mode (via the audio element) has support for partial content (http code 206) this means with this mode the song will start playing as soon as enough data has been buffered even though the song has not been fully loaded yet (it will load more data from the server in the background as the song progresses). The loading progress callback will return a percentage, which represents the amount of data that got loaded so far, which means it might not represent the loading state of the full song. If you want to display what parts of the song have been loaded more accurately (display the time range(s) that got loaded) I recommend using a [2D canvas element](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) and to get the ranges that have been loaded, I recommend you use the **audioElement** property of a song to get the audioElement that is loading the song and then read the [audioElement.buffered](https://developer.mozilla.org/en-US/docs/Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges) value(s).
You can use the PLAYER_MODE_AJAX if for example you want to build something where it doesn't matter that the song will only play after it has been fully loaded. However in this mode you can (pre-)load and maybe also cach sounds by yourself (you can inject an array buffer that you loaded yourself (via an XMLHttpRequest or using fetch) or even an already decoded audio buffer) by setting the sound.arrayBuffer or sound.audioBuffer. Use this mode if you prefer to have a smooth loading animation, because its loading progress callback is straight forward, when the loading progress callback gets triggered by the player, you can use the percentage value and pass it to a progress bar. To display the loading progress you could for example use a [HTML progress element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress), you can find such an example in the [simple player example](./examples/simple-player/README.md).
You can use the PLAYER_MODE_AJAX if for example you want to build something that has a lot (of small sounds that get loaded all at once) and eventually get (pre-)loaded and maybe cached by you (you can inject an array buffer that you loaded yourself or even a audio buffer you already decoded to the player via the sound attributes). Use this mode if you prefer to wait until the song has fully loaded and then gets played. Its progress callback is straight forward, when the loading progress callback gets triggered by the player, you can use the percentage value and pass it to a progress bar. To display the loading progress you could for example use a [HTML progress element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress), you can find such an example in the [simple player example](./examples/simple-player/README.md).
### advanced usage

@@ -472,14 +470,13 @@

* for audio mode, add option for songs "crossOrigin" to be set to "use-credentials" [HTML attribute: crossorigin](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) instead of "anonymous", "anonymous" could be kept as default value, also do the same for XHR calls (ajax mode) [XMLHttpRequest: withCredentials property](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
* add a song feature to fade out (current song) / fade in (next song) maybe two new options fadeInDuration and fadeOutDuration would be enough, if the values are set we do a fade
* add onDurationChange / onLoopChange callbacks to song(s)!?
* add loop song, loop queue, loop off examples to simple player example
* for audio mode, add option for songs "crossOrigin" to be set to "use-credentials" (https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) instead of "anonymous", "anonymous" could be kept as default value, also do the same for XHR calls (ajax mode) [XMLHttpRequest: withCredentials property](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
* add sound option to set the initial gain value of a sound, for now it is always 1 (1 = no change to loudness), (optional method that lets you define a modifier (or coefficient) per song by which the gain will be changed), useful if some songs are louder than others and you want to normalize the volume of all songs in a playlist to be similar
* add a song feature to fade out (current song) / fade in (next song) maybe two new options fadeInDuration and fadeOutDuration would be enough, if the values are set we do a fade
* add a shuffle songs feature, I thought about adding a PLAY_SHUFFLE(D) option for the play() function but then only the first song would be a random pick, so the player itself needs a shuffle mode which also shuffles the next songs, you need to be able to turn it on / off at any time
* today we have sound callbacks for events like "playing", "started"..., but would player callbacks be useful, we could add callbacks for things like an "onVolumeChange" event?
* is there a need to add more callbacks to songs, for native audio (element) events? [audio#events](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#events) ... are there equivalents for songs loaded in ajax mode
* today we have sound callbacks for events like "playing", "started"..., but would player callbacks be useful, we could add callbacks for things like an "onVolumeChange" event? [HTMLMediaElement Events](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement#events) ... the AudioBufferSourceNode does not have events (other than onended), even the playbackState got removed: [playbackState](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Migrating_from_webkitAudioContext#changes_to_determining_playback_state)
* would it be useful to have player events, so that callbacks can be added, directly the player itself, for things like "volumechange" and maybe act as alias for the events of the current song, like "on playing current song"?
* add an example where dev custom audiocontext gets connected to an [AnalyserNode](https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode) or oscilator node and then passed to player (to which we then connect the song gainnode and then connect that audiocontext to the destination)
* instead of having sound properties like "isReadyToPLay, isBuffered, isBuffering" it would be better to use the SOUND_STATE_XXX constants
* add (stereo) panning (maybe add an example of how to do it by injecting an audiocontext that has the panningnode attached already) <https://developer.mozilla.org/en-US/docs/Web/API/StereoPannerNode>
* use service worker to cache ajax requests when the player mode is ajax (audio buffer) <https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API>
* add (stereo) panning (maybe add an example of how to do it by injecting an audiocontext that has the panningnode attached already) [MDN: StereoPannerNode](https://developer.mozilla.org/en-US/docs/Web/API/StereoPannerNode)
* use service worker to cache ajax requests when the player mode is ajax (audio buffer) [MDN: Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)
* allow to add an array of sounds to queue all at once

@@ -486,0 +483,0 @@ * allow to add sound to queue after a sound by id (not just at beginning or end, as it is as of now)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc