web-audio-api-player
Advanced tools
Comparing version 5.2.1 to 5.3.0
@@ -573,2 +573,3 @@ /****************************************************************************** | ||
const WHERE_IN_QUEUE_AT_END = 'append'; | ||
const VISIBILITY_HIDDEN_ACTION_PAUSE = 'visibility_hidden_action_pause'; | ||
class PlayerCore { | ||
@@ -578,2 +579,3 @@ constructor(playerOptions = {}) { | ||
this._postMuteVolume = null; | ||
this._postVisibilityHiddenPlaying = null; | ||
this._progressTrigger = (sound, timestamp) => { | ||
@@ -611,3 +613,4 @@ const currentSound = this._getSoundFromQueue({ whichSound: PlayerCore.CURRENT_SOUND }); | ||
stopOnReset: true, | ||
visibilityAutoMute: false, | ||
visibilityWatch: false, | ||
visibilityHiddenAction: VISIBILITY_HIDDEN_ACTION_PAUSE, | ||
unlockAudioOnFirstUserInteraction: false, | ||
@@ -1321,5 +1324,5 @@ persistVolume: true, | ||
} | ||
setVisibilityAutoMute(visibilityAutoMute) { | ||
this._options.visibilityAutoMute = visibilityAutoMute; | ||
if (visibilityAutoMute) { | ||
setVisibilityWatch(visibilityWatch) { | ||
this._options.visibilityWatch = visibilityWatch; | ||
if (visibilityWatch) { | ||
document.addEventListener('visibilitychange', this._handleVisibilityChange.bind(this), false); | ||
@@ -1331,5 +1334,11 @@ } | ||
} | ||
getVisibilityAutoMute() { | ||
return this._options.visibilityAutoMute; | ||
getVisibilityWatch() { | ||
return this._options.visibilityWatch; | ||
} | ||
setVisibilityHiddenAction(visibilityHiddenAction) { | ||
this._options.visibilityHiddenAction = visibilityHiddenAction; | ||
} | ||
getVisibilityHiddenAction() { | ||
return this._options.visibilityHiddenAction; | ||
} | ||
_handleVisibilityChange() { | ||
@@ -1347,6 +1356,26 @@ let hiddenKeyword; | ||
if (document[hiddenKeyword]) { | ||
this.mute(); | ||
if (this._options.visibilityHiddenAction === PlayerCore.VISIBILITY_HIDDEN_ACTION_PAUSE) { | ||
const currentSound = this._getSoundFromQueue({ whichSound: PlayerCore.CURRENT_SOUND }); | ||
if (currentSound === null) { | ||
return; | ||
} | ||
if (currentSound.state === PlayerSound.SOUND_STATE_PLAYING) { | ||
this.pause(); | ||
this._postVisibilityHiddenPlaying = true; | ||
} | ||
else { | ||
this._postVisibilityHiddenPlaying = false; | ||
} | ||
} | ||
else if (this._options.visibilityHiddenAction === PlayerCore.VISIBILITY_HIDDEN_ACTION_MUTE) { | ||
this.mute(); | ||
} | ||
} | ||
else { | ||
this.unMute(); | ||
if (this._options.visibilityHiddenAction === PlayerCore.VISIBILITY_HIDDEN_ACTION_PAUSE && this._postVisibilityHiddenPlaying === true) { | ||
this.play(); | ||
} | ||
else if (this._options.visibilityHiddenAction === PlayerCore.VISIBILITY_HIDDEN_ACTION_MUTE) { | ||
this.unMute(); | ||
} | ||
} | ||
@@ -1390,4 +1419,6 @@ } | ||
PlayerCore.PLAYER_MODE_FETCH = 'player_mode_fetch'; | ||
PlayerCore.VISIBILITY_HIDDEN_ACTION_MUTE = 'visibility_hidden_action_mute'; | ||
PlayerCore.VISIBILITY_HIDDEN_ACTION_PAUSE = 'visibility_hidden_action_pause'; | ||
export { PlayerCore, PlayerSound }; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
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.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,this.elapsedPlayTime=0,this.seekPercentage=0,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,this.seekPercentage=e.seekPercentage||0,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(){return this.duration}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){e.seekPercentage=Math.round(t);const i=e.getDuration();null===i||isNaN(i)?yield this.loadSound(e,n.AFTER_LOADING_SEEK):this._setPosition(e)}}))}_setPosition(e){const t=e.getDuration()/100*e.seekPercentage;this.setPositionInSeconds(t,e)}setPositionInSeconds(i,o){return e(this,void 0,void 0,(function*(){let e=null;if(e=void 0!==o?o:this._getSoundFromQueue({whichSound:n.CURRENT_SOUND}),null!==e){!isNaN(e.duration)&&i>=e.duration&&(i=e.duration-.1);const o=e.state;if(e.state=t.SOUND_STATE_SEEKING,null!==e.onSeeking){const t=i,o=e.getDuration(),n=t/o*100,s=Math.round(n);e.onSeeking(s,o,t)}o===t.SOUND_STATE_PLAYING?(e.playTime=i,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?(e.elapsedPlayTime=i,yield this._stop(e)):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(yield this._play(e))):e.playTime=i}}))}loadSound(t,i){return e(this,void 0,void 0,(function*(){switch(this._options.loadPlayerMode){case n.PLAYER_MODE_AUDIO:yield this._loadSoundUsingAudioElement(t,i);break;case n.PLAYER_MODE_AJAX:yield this._loadSoundUsingRequest(t,i);case n.PLAYER_MODE_FETCH:}return t}))}_loadSoundUsingAudioElement(t,i){return e(this,void 0,void 0,(function*(){const{url:o,codec:s=null}=this._findBestSource(t.source);if(t.url=o,t.codec=s,null===t.url)throw new Error("sound has no url");{t.audioElement=yield this._playerAudio.getAudioElement(),t.audioElement.onprogress=()=>{if(t.audioElement.buffered.length){let e;const i=t.audioElement.buffered.end(0),o=t.getDuration();if(void 0!==o){const t=100/(o/i);e=Math.round(t)}t.loadingProgress=e,null!==t.onLoading&&t.onLoading(e,o,i),100===e&&(t.isBuffering=!1,t.isBuffered=!0,t.audioBufferDate=new Date)}};const o=()=>e(this,void 0,void 0,(function*(){switch(t.audioElement.removeEventListener("canplaythrough",o),t.isReadyToPLay=!0,isNaN(t.audioElement.duration)||t.durationSetManually||(t.duration=t.audioElement.duration),i){case n.AFTER_LOADING_SEEK:this._setPosition(t);break;case n.AFTER_LOADING_PLAY:this._play(t)}}));t.audioElement.addEventListener("canplaythrough",o),t.audioElement.crossOrigin="anonymous",t.audioElement.src=t.url,t.audioElement.load()}}))}_loadSoundUsingRequest(t,i){return e(this,void 0,void 0,(function*(){if(null!==t.arrayBuffer)return yield this._decodeSound(t);const{url:e,codec:n=null}=this._findBestSource(t.source);if(t.url=e,t.codec=n,null===t.url)throw new Error("sound has no url");{const e=new o;t.isBuffering=!0;const n=yield e.getArrayBuffer(t);t.arrayBuffer=n,yield this._decodeSound(t,i)}}))}_decodeSound(t,i){return e(this,void 0,void 0,(function*(){const e=t.arrayBuffer.slice(0),o=yield this._playerAudio.decodeAudio(e);switch(isNaN(o.duration)||t.durationSetManually||(t.duration=o.duration),t.audioBuffer=o,t.isBuffering=!1,t.isBuffered=!0,t.audioBufferDate=new Date,t.isReadyToPLay=!0,i){case n.AFTER_LOADING_SEEK:this._setPosition(t);break;case n.AFTER_LOADING_PLAY: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||(e.state=t.SOUND_STATE_STOPPED,yield this._stop(e)),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,n.AFTER_LOADING_PLAY),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),e.state=t.SOUND_STATE_PAUSED,yield this._stop(e),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),e.state=t.SOUND_STATE_STOPPED,yield this._stop(e),e}))}_stop(i){return e(this,void 0,void 0,(function*(){null!==this._playingProgressRequestId&&(cancelAnimationFrame(this._playingProgressRequestId),this._playingProgressRequestId=null),null!==i.sourceNode&&(i.sourceNode instanceof AudioBufferSourceNode&&(i.sourceNode.stop(0),yield this._playerAudio.disconnectSound(i)),i.sourceNode instanceof MediaElementAudioSourceNode&&i.audioElement.pause()),i.state===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.AFTER_LOADING_SEEK="after_loading_seek",n.AFTER_LOADING_PLAY="after_loading_play",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,i,t,o){return new(t||(t=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 i;e.done?n(e.value):(i=e.value,i instanceof t?i:new t((function(e){e(i)}))).then(u,d)}r((o=o.apply(e,i||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class i{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.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,this.elapsedPlayTime=0,this.seekPercentage=0,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,this.seekPercentage=e.seekPercentage||0,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(){return this.duration}setDuration(e){isNaN(e)||(this.duration=e,this.durationSetManually=!0)}setLoop(e){this.loop=e,this.state===i.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)}}i.SOUND_STATE_STOPPED="sound_state_stopped",i.SOUND_STATE_PAUSED="sound_state_paused",i.SOUND_STATE_PLAYING="sound_state_playing",i.SOUND_STATE_SEEKING="sound_state_seeking";class t{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(i){return e(this,void 0,void 0,(function*(){const e=yield this.getAudioContext();return yield e.decodeAudioData(i)}))}_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,i)=>{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,i())))}this.getAudioContext().then((()=>{const i=this._audioContext.createBuffer(1,1,22050);let t=this._audioContext.createBufferSource();t.onended=()=>(t.disconnect(0),this._removeFirstUserInteractionEventListeners(),t.disconnect(0),t.buffer=null,t=null,this._isAudioUnlocked=!0,this._isAudioUnlocking=!1,e()),t.buffer=i,t.connect(this._audioContext.destination),t.start(0)})).catch((e=>(this._isAudioUnlocking=!1,i())))}))}_createAudioElementAndSource(){return e(this,void 0,void 0,(function*(){yield this._createAudioElement(),yield this._createMediaElementAudioSourceNode()}))}_createAudioElement(i){return e(this,void 0,void 0,(function*(){if(null===this._audioElement||!0===i){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(i){return e(this,void 0,void 0,(function*(){this._removeFirstUserInteractionEventListeners(),i.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 i=yield this.getAudioContext();e=i.createGain(),this._initializeVolume(e),e.connect(i.destination),this._audioNodes.gainNode=e}return e}))}_disconnectPlayerGainNode(){null!==this._audioNodes.gainNode&&(this._audioNodes.gainNode.disconnect(),this._audioNodes.gainNode=null)}connectSound(i,t){return e(this,void 0,void 0,(function*(){if(i.isConnectToPlayerGain)return;if("player_mode_ajax"===this._options.loadPlayerMode){const e=yield this._createAudioBufferSourceNode();i.gainNode=e.context.createGain(),e.connect(i.gainNode),e.loop=i.loop,e.onended=t,i.sourceNode=e}else"player_mode_audio"===this._options.loadPlayerMode&&(yield this._createAudioElementAndSource(),i.gainNode=this._mediaElementAudioSourceNode.context.createGain(),this._mediaElementAudioSourceNode.connect(i.gainNode),this._mediaElementAudioSourceNode.mediaElement.loop=i.loop,this._mediaElementAudioSourceNode.mediaElement.onended=t,i.sourceNode=this._mediaElementAudioSourceNode);i.gainNode.gain.value=1;const e=yield this._getPlayerGainNode();i.gainNode.connect(e),i.isConnectToPlayerGain=!0}))}disconnectSound(i){return e(this,void 0,void 0,(function*(){i.isConnectToPlayerGain&&(null!==i.sourceNode&&(i.sourceNode.disconnect(),i.sourceNode=null),null!==i.gainNode&&(i.gainNode.disconnect(),i.gainNode=null,i.isConnectToPlayerGain=!1),null!==i.audioElement&&(i.audioElement=null))}))}_changePlayerGainValue(i){return e(this,void 0,void 0,(function*(){if(this._audioNodes.gainNode instanceof GainNode){const e=yield this.getAudioContext(),t=(!isNaN(this._options.volumeTransitionTime)&&this._options.volumeTransitionTime>0?this._options.volumeTransitionTime:100)/1e3;try{this._audioNodes.gainNode.gain.setTargetAtTime(i,e.currentTime,t)}catch(e){}}}))}setVolume(i,t=!0){return e(this,void 0,void 0,(function*(){this._options.persistVolume&&t&&localStorage.setItem("WebAudioAPIPlayerVolume",i.toString());const e=i/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=i,i}))}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 i=parseInt(localStorage.getItem("WebAudioAPIPlayerVolume")),t=i/100;isNaN(i)||(e.gain.value=t),this._volume=i}if(null===this._volume){const i=this._options.volume/100;e.gain.value=i,this._volume=this._options.volume}}}class o{getArrayBuffer(e){return new Promise((function(i,t){const o=new XMLHttpRequest;o.open("GET",e.url,!0),o.responseType="arraybuffer",o.onload=function(){o.status>=200&&o.status<=299?i(o.response):t(new Error(o.statusText+"(status:"+o.status+")"))},o.onprogress=function(i){const t=100/(i.total/i.loaded),o=Math.round(t);e.loadingProgress=o,null!==e.onLoading&&e.onLoading(o,i.total,i.loaded)},o.onerror=function(e){t(e)},o.send()}))}}class n{constructor(e={}){this._playingProgressRequestId=null,this._postMuteVolume=null,this._postVisibilityHiddenPlaying=null,this._progressTrigger=(e,t)=>{const o=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(e.id===o.id&&o.state===i.SOUND_STATE_PLAYING){if(t-this._playingProgressPreviousTimestamp>=this._options.playingProgressIntervalTime){const i=e.getCurrentTime(),o=e.getDuration();if(!isNaN(i)&&!isNaN(o)){let n=0;if(0!==i){const e=i/o*100;n=Math.round(e)}e.playedTimePercentage=n,e.playTime=i,e.onPlaying(n,o,i),this._playingProgressPreviousTimestamp=t}}this._playingProgressRequestId=window.requestAnimationFrame((i=>{this._progressTrigger(e,i)}))}};const t={volume:80,loopQueue:!1,loopSong:!1,soundsBaseUrl:"",playingProgressIntervalTime:200,playNextOnEnded:!0,stopOnReset:!0,visibilityWatch:!1,visibilityHiddenAction:"visibility_hidden_action_pause",unlockAudioOnFirstUserInteraction:!1,persistVolume:!0,loadPlayerMode:"player_mode_audio",audioContext:null,addAudioElementsToDom:!1,volumeTransitionTime:100},o=Object.assign({},t,e);this._queue=[],this._currentIndex=0,this._options=o,this._playingProgressPreviousTimestamp=0,this._initialize()}_initialize(){const e=this._audioOptions();switch(this._playerAudio=new t(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:t="append"}){const o=new i(e);switch(t){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(i){return e(this,void 0,void 0,(function*(){if(i<0||i>100)throw new Error("soundPositionInPercent must be a number >= 0 and <= 100");const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e){e.seekPercentage=Math.round(i);const t=e.getDuration();null===t||isNaN(t)?yield this.loadSound(e,n.AFTER_LOADING_SEEK):this._setPosition(e)}}))}_setPosition(e){const i=e.getDuration()/100*e.seekPercentage;this.setPositionInSeconds(i,e)}setPositionInSeconds(t,o){return e(this,void 0,void 0,(function*(){let e=null;if(e=void 0!==o?o:this._getSoundFromQueue({whichSound:n.CURRENT_SOUND}),null!==e){!isNaN(e.duration)&&t>=e.duration&&(t=e.duration-.1);const o=e.state;if(e.state=i.SOUND_STATE_SEEKING,null!==e.onSeeking){const i=t,o=e.getDuration(),n=i/o*100,s=Math.round(n);e.onSeeking(s,o,i)}o===i.SOUND_STATE_PLAYING?(e.playTime=t,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?(e.elapsedPlayTime=t,yield this._stop(e)):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(yield this._play(e))):e.playTime=t}}))}loadSound(i,t){return e(this,void 0,void 0,(function*(){switch(this._options.loadPlayerMode){case n.PLAYER_MODE_AUDIO:yield this._loadSoundUsingAudioElement(i,t);break;case n.PLAYER_MODE_AJAX:yield this._loadSoundUsingRequest(i,t);case n.PLAYER_MODE_FETCH:}return i}))}_loadSoundUsingAudioElement(i,t){return e(this,void 0,void 0,(function*(){const{url:o,codec:s=null}=this._findBestSource(i.source);if(i.url=o,i.codec=s,null===i.url)throw new Error("sound has no url");{i.audioElement=yield this._playerAudio.getAudioElement(),i.audioElement.onprogress=()=>{if(i.audioElement.buffered.length){let e;const t=i.audioElement.buffered.end(0),o=i.getDuration();if(void 0!==o){const i=100/(o/t);e=Math.round(i)}i.loadingProgress=e,null!==i.onLoading&&i.onLoading(e,o,t),100===e&&(i.isBuffering=!1,i.isBuffered=!0,i.audioBufferDate=new Date)}};const o=()=>e(this,void 0,void 0,(function*(){switch(i.audioElement.removeEventListener("canplaythrough",o),i.isReadyToPLay=!0,isNaN(i.audioElement.duration)||i.durationSetManually||(i.duration=i.audioElement.duration),t){case n.AFTER_LOADING_SEEK:this._setPosition(i);break;case n.AFTER_LOADING_PLAY:this._play(i)}}));i.audioElement.addEventListener("canplaythrough",o),i.audioElement.crossOrigin="anonymous",i.audioElement.src=i.url,i.audioElement.load()}}))}_loadSoundUsingRequest(i,t){return e(this,void 0,void 0,(function*(){if(null!==i.arrayBuffer)return yield this._decodeSound(i);const{url:e,codec:n=null}=this._findBestSource(i.source);if(i.url=e,i.codec=n,null===i.url)throw new Error("sound has no url");{const e=new o;i.isBuffering=!0;const n=yield e.getArrayBuffer(i);i.arrayBuffer=n,yield this._decodeSound(i,t)}}))}_decodeSound(i,t){return e(this,void 0,void 0,(function*(){const e=i.arrayBuffer.slice(0),o=yield this._playerAudio.decodeAudio(e);switch(isNaN(o.duration)||i.durationSetManually||(i.duration=o.duration),i.audioBuffer=o,i.isBuffering=!1,i.isBuffered=!0,i.audioBufferDate=new Date,i.isReadyToPLay=!0,t){case n.AFTER_LOADING_SEEK:this._setPosition(i);break;case n.AFTER_LOADING_PLAY:this._play(i)}}))}play({whichSound:t,playTimeOffset:o}={}){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND}),s=this._getSoundFromQueue({whichSound:t,updateIndex:!0});return null===s?s:null!==e&&e.state===i.SOUND_STATE_PLAYING&&e.id===s.id?(isNaN(o)||this.setPositionInSeconds(o),s):(null===e||e.state!==i.SOUND_STATE_PLAYING&&e.state!==i.SOUND_STATE_PAUSED||e.id===s.id||(e.state=i.SOUND_STATE_STOPPED,yield this._stop(e)),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,n.AFTER_LOADING_PLAY),s)}))}_play(t){return e(this,void 0,void 0,(function*(){t.state!==i.SOUND_STATE_PLAYING&&(this._playerAudio.isAudioContextFrozen()&&(yield this._playerAudio.unfreezeAudioContext()),t.playTimeOffset>0&&(t.playTime=t.playTimeOffset),this._options.loadPlayerMode===n.PLAYER_MODE_AJAX?yield this._playAudioBuffer(t):this._options.loadPlayerMode===n.PLAYER_MODE_AUDIO&&(yield this._playMediaElementAudio(t)),t.state=i.SOUND_STATE_PLAYING,this._triggerSoundCallbacks(t))}))}_playAudioBuffer(t){return e(this,void 0,void 0,(function*(){if(t.sourceNode instanceof AudioBufferSourceNode){t.startTime=t.sourceNode.context.currentTime,t.sourceNode.buffer=t.audioBuffer;try{t.state===i.SOUND_STATE_SEEKING||t.state===i.SOUND_STATE_PAUSED&&0===t.playTimeOffset?t.sourceNode.start(0,t.playTime):t.playTimeOffset>0?(t.playTimeOffset,Math.ceil(t.duration),t.elapsedPlayTime=t.playTimeOffset,t.sourceNode.start(0,t.playTimeOffset)):t.sourceNode.start()}catch(e){throw new Error(e)}}}))}_playMediaElementAudio(t){return e(this,void 0,void 0,(function*(){if(t.sourceNode instanceof MediaElementAudioSourceNode)return t.state===i.SOUND_STATE_SEEKING||t.state===i.SOUND_STATE_PAUSED&&0===t.playTimeOffset?t.audioElement.currentTime=t.playTime:t.playTimeOffset>0?(t.playTimeOffset,Math.ceil(t.duration),t.audioElement.currentTime=t.playTimeOffset):t.audioElement.currentTime=0,yield t.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===i.SOUND_STATE_PLAYING){let i=!1;null!==this._getSoundFromQueue({whichSound:n.PLAY_SOUND_NEXT})&&(i=!0),i||(yield this._playerAudio.freezeAudioContext()),null!==e.onEnded&&e.onEnded(i);try{i&&(yield this.next())}catch(e){}}if(this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&e.state===i.SOUND_STATE_SEEKING)try{yield this.play(e)}catch(e){}}}}))}_getSoundFromQueue({whichSound:e,updateIndex:i=!1}={}){let t=null,o=null;if(0===this._queue.length)return t;switch(void 0===e&&(e=n.CURRENT_SOUND),e){case n.CURRENT_SOUND:o=this._currentIndex,t=this._queue[o];break;case n.PLAY_SOUND_NEXT:void 0!==this._queue[this._currentIndex+1]?(o=this._currentIndex+1,t=this._queue[o]):this._options.loopQueue&&(o=0,t=this._queue[o]);break;case n.PLAY_SOUND_PREVIOUS:void 0!==this._queue[this._currentIndex-1]?(o=this._currentIndex-1,t=this._queue[o]):this._options.loopQueue&&(o=this._queue.length-1,t=this._queue[o]);break;case n.PLAY_SOUND_FIRST:this._queue.length>0&&(o=0,t=this._queue[o]);break;case n.PLAY_SOUND_LAST:this._queue.length>0&&(o=this._queue.length-1,t=this._queue[o]);break;default:[t,o]=this._findSoundById({soundId:e})}return null!==o&&i&&(this._currentIndex=o),t}_findSoundById({soundId:e}){let i=null,t=0;return this._queue.some(((o,n)=>{if(o.id===e)return i=o,t=n,!0})),[i,t]}_findBestSource(e){const i={url:null,codec:null};let t;t=Array.isArray(e)?e:[e];let o=0;for(;o<t.length;){const e=t[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){i.url=n,i.codec=e.codec;break}i.url=n,i.codec=e.codec}o++}return i}_checkCodecSupport(e){let i,t="";switch(e){case"ogg":case"oga":i=['audio/ogg; codecs="vorbis"'];break;case"mp3":i=['audio/mpeg; codecs="mp3"'];break;case"opus":i=['audio/ogg; codecs="opus"','audio/webm; codecs="opus"'];break;case"wav":i=['audio/wav; codecs="1"'];break;case"m4a":i=["audio/m4a;","audio/x-m4a;"];break;case"m4p":i=["audio/m4p;","audio/x-m4p;"];break;case"caf":i=["audio/x-caf;"];break;case"aac":i=["audio/aac;"];break;case"weba":case"webm":i=['audio/webm; codecs="vorbis"'];break;case"flac":i=["audio/flac;","audio/x-flac;"];break;default:t="unrecognised codec"}if(t)throw new Error(t);return this._checkMimeTypesSupport(i)}_checkMimeTypesSupport(e){const i=new Audio;let t=!1;return e.forEach((e=>{i.canPlayType(e).replace(/^no$/,"")&&(t=!0)})),t}pause(){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null===e)return;if(e.state===i.SOUND_STATE_PAUSED)return;const t=e.getCurrentTime();return e.playTime=t,this._options.loadPlayerMode===n.PLAYER_MODE_AJAX&&(e.elapsedPlayTime=t),null!==e.onPaused&&e.onPaused(e.playTime),e.state=i.SOUND_STATE_PAUSED,yield this._stop(e),e}))}stop(){return e(this,void 0,void 0,(function*(){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null!==e&&e.state!==i.SOUND_STATE_STOPPED)return yield this._playerAudio.freezeAudioContext(),null!==e.onStopped&&e.onStopped(e.playTime),e.state=i.SOUND_STATE_STOPPED,yield this._stop(e),e}))}_stop(t){return e(this,void 0,void 0,(function*(){null!==this._playingProgressRequestId&&(cancelAnimationFrame(this._playingProgressRequestId),this._playingProgressRequestId=null),null!==t.sourceNode&&(t.sourceNode instanceof AudioBufferSourceNode&&(t.sourceNode.stop(0),yield this._playerAudio.disconnectSound(t)),t.sourceNode instanceof MediaElementAudioSourceNode&&t.audioElement.pause()),t.state===i.SOUND_STATE_STOPPED&&(t.isReadyToPLay=!1,t.firstTimePlayed=!0,t.startTime=0,t.elapsedPlayTime=0,t.playTime=0,t.playedTimePercentage=0,yield this._playerAudio.disconnectSound(t))}))}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})}))}setVisibilityWatch(e){this._options.visibilityWatch=e,e?document.addEventListener("visibilitychange",this._handleVisibilityChange.bind(this),!1):document.removeEventListener("visibilitychange",this._handleVisibilityChange.bind(this),!1)}getVisibilityWatch(){return this._options.visibilityWatch}setVisibilityHiddenAction(e){this._options.visibilityHiddenAction=e}getVisibilityHiddenAction(){return this._options.visibilityHiddenAction}_handleVisibilityChange(){let e;if(void 0!==document.hidden?e="hidden":void 0!==document.msHidden?e="msHidden":void 0!==document.webkitHidden&&(e="webkitHidden"),document[e])if(this._options.visibilityHiddenAction===n.VISIBILITY_HIDDEN_ACTION_PAUSE){const e=this._getSoundFromQueue({whichSound:n.CURRENT_SOUND});if(null===e)return;e.state===i.SOUND_STATE_PLAYING?(this.pause(),this._postVisibilityHiddenPlaying=!0):this._postVisibilityHiddenPlaying=!1}else this._options.visibilityHiddenAction===n.VISIBILITY_HIDDEN_ACTION_MUTE&&this.mute();else this._options.visibilityHiddenAction===n.VISIBILITY_HIDDEN_ACTION_PAUSE&&!0===this._postVisibilityHiddenPlaying?this.play():this._options.visibilityHiddenAction===n.VISIBILITY_HIDDEN_ACTION_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.AFTER_LOADING_SEEK="after_loading_seek",n.AFTER_LOADING_PLAY="after_loading_play",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",n.VISIBILITY_HIDDEN_ACTION_MUTE="visibility_hidden_action_mute",n.VISIBILITY_HIDDEN_ACTION_PAUSE="visibility_hidden_action_pause";export{n as PlayerCore,i as PlayerSound}; | ||
//# sourceMappingURL=index.min.js.map |
@@ -10,5 +10,8 @@ import { ISound, ISoundAttributes, ISoundSource } from './sound'; | ||
declare const AFTER_LOADING_PLAY = "after_loading_play"; | ||
declare const VISIBILITY_HIDDEN_ACTION_MUTE = "visibility_hidden_action_mute"; | ||
declare const VISIBILITY_HIDDEN_ACTION_PAUSE = "visibility_hidden_action_pause"; | ||
type typePlayerMode = typeof PLAYER_MODE_AUDIO | typeof PLAYER_MODE_AJAX | typeof PLAYER_MODE_FETCH; | ||
type typeWhereInQueue = typeof WHERE_IN_QUEUE_AT_START | typeof WHERE_IN_QUEUE_AT_END; | ||
type typeAfterLoadingAction = typeof AFTER_LOADING_SEEK | typeof AFTER_LOADING_PLAY; | ||
type typeVisibilityHiddenAction = typeof VISIBILITY_HIDDEN_ACTION_MUTE | typeof VISIBILITY_HIDDEN_ACTION_PAUSE; | ||
export interface ICoreOptions { | ||
@@ -22,3 +25,4 @@ volume?: number; | ||
stopOnReset?: boolean; | ||
visibilityAutoMute?: boolean; | ||
visibilityWatch?: boolean; | ||
visibilityHiddenAction?: typeVisibilityHiddenAction; | ||
unlockAudioOnFirstUserInteraction?: boolean; | ||
@@ -57,2 +61,3 @@ persistVolume?: boolean; | ||
protected _postMuteVolume: number; | ||
protected _postVisibilityHiddenPlaying: boolean; | ||
protected _options: ICoreOptions; | ||
@@ -71,2 +76,4 @@ static readonly WHERE_IN_QUEUE_AT_END = "append"; | ||
static readonly PLAYER_MODE_FETCH = "player_mode_fetch"; | ||
static readonly VISIBILITY_HIDDEN_ACTION_MUTE = "visibility_hidden_action_mute"; | ||
static readonly VISIBILITY_HIDDEN_ACTION_PAUSE = "visibility_hidden_action_pause"; | ||
constructor(playerOptions?: ICoreOptions); | ||
@@ -114,4 +121,6 @@ protected _initialize(): void; | ||
last(): Promise<ISound>; | ||
setVisibilityAutoMute(visibilityAutoMute: boolean): void; | ||
getVisibilityAutoMute(): boolean; | ||
setVisibilityWatch(visibilityWatch: boolean): void; | ||
getVisibilityWatch(): boolean; | ||
setVisibilityHiddenAction(visibilityHiddenAction: typeVisibilityHiddenAction): void; | ||
getVisibilityHiddenAction(): typeVisibilityHiddenAction; | ||
protected _handleVisibilityChange(): void; | ||
@@ -118,0 +127,0 @@ manuallyUnlockAudio(): Promise<void>; |
{ | ||
"name": "web-audio-api-player", | ||
"version": "5.2.1", | ||
"version": "5.3.0", | ||
"description": "web audio api player", | ||
@@ -43,11 +43,11 @@ "keywords": [ | ||
"@rollup/plugin-terser": "0.4.4", | ||
"@typescript-eslint/eslint-plugin": "6.11.0", | ||
"@typescript-eslint/parser": "6.11.0", | ||
"eslint": "8.53.0", | ||
"eslint-plugin-import": "2.29.0", | ||
"rollup": "4.4.1", | ||
"@typescript-eslint/eslint-plugin": "6.17.0", | ||
"@typescript-eslint/parser": "6.17.0", | ||
"eslint": "8.56.0", | ||
"eslint-plugin-import": "2.29.1", | ||
"rollup": "4.9.2", | ||
"rollup-plugin-typescript2": "0.36.0", | ||
"typescript": "5.2.2" | ||
"typescript": "5.3.3" | ||
}, | ||
"type": "module" | ||
} |
@@ -62,6 +62,7 @@ [![npm version](https://img.shields.io/npm/v/web-audio-api-player.svg?style=flat)](https://www.npmjs.com/package/web-audio-api-player) | ||
Note: the **soundsBaseUrl** is the first option we set, it will tell the player what the full URL for the songs source is (for example <https://www.example.com/songs/>) or if the player and songs are hosted on the same domain the path is enough, **loopQueue** by default is set to false, I enable it here, this means that at the end of a queue (a playlist) the player won't stop but instead go back to the first song and play that song | ||
> [!NOTE] | ||
> the **soundsBaseUrl** is the first option we set, it will tell the player what the full URL for the songs source is (for example <https://www.example.com/songs/>) or if the player and songs are hosted on the same domain the path is enough, **loopQueue** by default is set to false, I enable it here, this means that at the end of a queue (a playlist) the player won't stop but instead go back to the first song and play that song | ||
> | ||
> for a full list of all available player options check out the [player options chapter](#player-options) | ||
Note 2: for a full list of all available player options check out the [player options chapter](#player-options) | ||
next we initialize the player using our options object and get a player instance in return: | ||
@@ -94,3 +95,4 @@ | ||
Note: for a full list of all available sound attributes check out the [sound attributes chapter](#sound-attributes) | ||
> [!TIP] | ||
> for a full list of all available sound attributes check out the [sound attributes chapter](#sound-attributes) | ||
@@ -160,8 +162,14 @@ after we have set the attributes for our first song we pass these attributes to the player queue: | ||
or you want to player to be muted when the browser of the user goes into the background then you can still enable the option: | ||
or you want to player to pause playing (or mute depending on what action you chose) the current song when the browser / app gets put into the background, then you can enable the option like this: | ||
```ts | ||
player.setVisibilityAutoMute(true) | ||
player.setVisibilityWatch(true) | ||
``` | ||
to change what happens when the visibility API detects that the player is hidden, you can use the following setter: | ||
```ts | ||
player.setVisibilityHiddenAction(PlayerCore.VISIBILITY_HIDDEN_ACTION_PAUSE) // or PlayerCore.VISIBILITY_HIDDEN_ACTION_MUTE | ||
``` | ||
or you want the queue to make a loop when the last song in the player queue (your playlist) finishes playing, then you would enable / disable it like this: | ||
@@ -173,3 +181,4 @@ | ||
Note: all of these setters have a corresponding getter, so if you want to now what the current value is, for example if you want to know what the current volume is set to: | ||
> [!NOTE] | ||
> all of these setters have a corresponding getter, so if you want to now what the current value is, for example if you want to know what the current volume is set to: | ||
@@ -226,3 +235,4 @@ ```ts | ||
Note: if you use typescript, import the **ICoreOptions** interface along with the playerCore, this makes it a lot easier to see what player options are available and what the type of each value is | ||
> [!TIP] | ||
> if you use typescript, import the **ICoreOptions** interface along with the playerCore, this makes it a lot easier to see what player options are available and what the type of each value is | ||
@@ -235,3 +245,4 @@ * volume: [number] (default: 80) the current playback volume | ||
* stopOnReset: [boolean] (default: true) when the queue gets reset and a sound is currently being played, should the player stop or continue playing that sound | ||
* visibilityAutoMute: [boolean] (default: false) tells the player if a sound is playing and the visibility API triggers a visibility change event, if the currently playing sound should get muted or not, uses the [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) internally | ||
* visibilityWatch: [boolean] (default: false) tells the player that if a sound is playing and the visibility API triggers a visibility change event, then the sound should get paused or muted (depending on what action is set to get executed on visibility is hidden), uses the [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) internally | ||
* visibilityHiddenAction: [typeVisibilityHiddenAction] (default: VISIBILITY_HIDDEN_ACTION_PAUSE) chose what action should get executed on visibility is hidden, if set to **VISIBILITY_HIDDEN_ACTION_PAUSE** the sound will get paused on visibility hidden and will start playing again when the visibility API triggers an event that tells the player that it is visible again, if set to **VISIBILITY_HIDDEN_ACTION_MUTE** the song will continue to play but the player will get muted on visibility hidden and unmuted when it becomes visible again | ||
* unlockAudioOnFirstUserInteraction: [boolean] (default: false) this tells the player to attempt to unlock audio as soon as possible, so that you can call the player play() method programmatically at any time, if you don't want to the player to handle this part and prefer to do it manually then you can use the [player function](#player-functions) called **manuallyUnlockAudio()**, for more info about this check out the chapter ["locked audio on mobile"](#locked-audio-on-mobile) | ||
@@ -246,3 +257,4 @@ * 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 | ||
Note: all player functions a promise, I recommend using a try catch and await the promise or call promise.catch to fetch eventual errors thrown by the player, like so: | ||
> [!TIP] | ||
> all player functions return a promise, I recommend using a try catch and await the promise or call promise.catch to fetch eventual errors thrown by the player, like so: | ||
@@ -280,3 +292,4 @@ ```ts | ||
Note: the playTimeOffset (if set) will always get honored, so if you want to resume after a pause don't set the playTimeOffset, if playTimeOffset is set the song will start at the specified position, if no playTimeOffset is set the player will use the songs playTime value, which is 0 for a song that gets played for the first time or a value > 0 for a song that was paused | ||
> [!NOTE] | ||
> the playTimeOffset (if set) will always get honored, so if you want to resume after a pause don't set the playTimeOffset, if playTimeOffset is set the song will start at the specified position, if no playTimeOffset is set the player will use the songs playTime value, which is 0 for a song that gets played for the first time or a value > 0 for a song that was paused | ||
@@ -315,4 +328,6 @@ * pause() **pauses playback**, returns a promise that when resolved returns the current sound | ||
* setPositionInSeconds(soundPositionInSeconds: number): used to change the position of the song that is currently playing in seconds, the number should be smaller than the duration of the song, returns a promise | ||
* setVisibilityAutoMute(visibilityAutoMute: boolean) a boolean value to change the **visibilityAutoMute** option of the player, if true the player will be muted when the visibility API [MDN visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) notices that the browser is in the background, will get unmuted when the visibility API notices that the browser is in the foreground again, if false the volume will not be automatically muted when the visibility changes | ||
* getVisibilityAutoMute() get the current boolean value that is set for the **visibilityAutoMute** option | ||
* setVisibilityWatch(visibilityWatch: boolean) a boolean value to change the **visibilityWatch** option of the player, if true the player will be paused / muted when the visibility API [MDN visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) triggers an event that tells the player that the browser / app is in the background, will start playing again or get unmuted when the visibility API notices that the browser is in the foreground again, if false visibility changes will get ignored by the player | ||
* getVisibilityWatch() get the current boolean value that is set for the **visibilityWatch** option | ||
* setVisibilityHiddenAction(visibilityHiddenAction: typeVisibilityHiddenAction) change what action will get executed when the visibility API detects that the player is hidden / visible again, see [player option](#player-options) for more details | ||
* getVisibilityHiddenAction() get the current action that is set for the **visibilityHiddenAction** option | ||
* disconnect() disconnects the player and destroys all songs in the queue, this function should get called for example in react when a component unmounts, call this function when you don't need the player anymore to free memory | ||
@@ -326,3 +341,4 @@ * getAudioContext() get the current audioContext that is being used by the player [MDN audiocontext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) | ||
Note: if you use typescript, import the **ISoundAttributes** interface along with the playerCore, this makes it a lot easier to see what sound attributes are available and what the type of each value is | ||
> [!TIP] | ||
> if you use typescript, import the **ISoundAttributes** interface along with the playerCore, this makes it a lot easier to see what sound attributes are available and what the type of each value is | ||
@@ -366,3 +382,4 @@ **sound options:** | ||
Note: If the user clicks on a play button and call player.play() then audio will play just fine, this chapter is about audio not playing when calling player.play() before the user interacted with the page (app) | ||
> [!NOTE] | ||
> If the user clicks on a play button and call player.play() then audio will play just fine, this chapter is about audio not playing when calling player.play() before the user interacted with the page (app) | ||
@@ -373,4 +390,7 @@ If you attempt play a sound (song) on mobile programmatically (before a user interaction) then the mobile browser will throw a **NotAllowedError** error: | ||
Note: iOS (iPhone) and android mobile devices will throw that error, in the past iPad tablets would throw an error too, however newer versions are considered a desktop device and do not need throw an error | ||
so if you encounter this error on iOS (iPhone) and android mobile devices, then it means that you tried to play the sound programmatically before the browser got "unlocked" by a user interaction | ||
> [!NOTE] | ||
> in the past iPad tablets would throw an error too, however newer versions are considered a desktop device and do not need throw an error | ||
There is however a trick to unlock audio on mobile, the trick is to listen for events like a user clicking on something in your page and use that interaction to play a silent sound for a brief moment, after that audio will be unlocked and you will be able to trigger the play function at any time programmatically to play the song you want (even if it is not a direct action initiated by the user) | ||
@@ -386,3 +406,4 @@ | ||
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. | ||
> [!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. | ||
@@ -389,0 +410,0 @@ 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: |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
379095
1836
555