musquito
Advanced tools
Comparing version 2.0.1 to 2.0.2
@@ -1,1 +0,1 @@ | ||
module.exports = require('./dist/musquito-2.0.1'); | ||
module.exports = require('./dist/musquito-2.0.2'); |
{ | ||
"name": "musquito", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "An audio engine for HTML5 games and interactive websites", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -325,3 +325,3 @@ import engine, { EngineEvents, EngineState, ErrorType } from './Engine'; | ||
* Loads the sound to the underlying audio object. | ||
* @param {number} [soundId] The id of the sound to be loaded. | ||
* @param {number} [soundId] The id of the sound to be loaded (for stream types). | ||
* @return {Buzz} | ||
@@ -336,2 +336,3 @@ */ | ||
// If the sound is not of stream and the source is loaded or currently loading then return. | ||
if (!this._stream && (this.isLoaded() || this._loadState === LoadState.Loading)) { | ||
@@ -341,4 +342,6 @@ return this; | ||
// Set the state to loading. | ||
this._loadState = LoadState.Loading; | ||
// Increment the calls which is needed for stream types. | ||
this._noOfLoadCalls = this._noOfLoadCalls + 1; | ||
@@ -351,9 +354,10 @@ | ||
load$.then(downloadResult => { | ||
this._noOfLoadCalls > 0 && (this._noOfLoadCalls = this._noOfLoadCalls - 1); | ||
if (this._stream && this._state === BuzzState.Destroyed) { | ||
this._engine.releaseForGroup(this._compatibleSrc, this._id, this._loadState === LoadState.AudioUnLoad); | ||
if (this._stream && (this._state === BuzzState.Destroyed || this._loadState === LoadState.AudioUnLoad)) { | ||
this._engine.releaseForGroup(this._compatibleSrc, this._id, this._state !== BuzzState.Destroyed); | ||
return; | ||
} else if (this._state === BuzzState.Destroyed || this._loadState === LoadState.NotLoaded) { | ||
} | ||
if (this._state === BuzzState.Destroyed || this._loadState === LoadState.NotLoaded) { | ||
return; | ||
@@ -429,3 +433,3 @@ } | ||
// and so we are destroying it. | ||
this._engine.destroyAllocatedAudio(this._compatibleSrc, newSoundId, this._id); | ||
this._engine.releaseForSound(this._compatibleSrc, newSoundId, this._id); | ||
this._engine.removeSound(this._compatibleSrc, this._id, newSoundId); | ||
@@ -438,3 +442,3 @@ this._fire(BuzzEvents.Destroy, newSoundId); | ||
this._fire(BuzzEvents.Error, { type: ErrorType.LoadError, soundId: newSoundId, error: err }); | ||
this._engine.destroyAllocatedAudio(this._compatibleSrc, this._id, newSoundId); | ||
this._engine.releaseForSound(this._compatibleSrc, this._id, newSoundId); | ||
sound.destroy(); | ||
@@ -441,0 +445,0 @@ }, |
@@ -354,11 +354,12 @@ import BufferLoader from './BufferLoader'; | ||
* @param {string|string[]} [urls] Single or array of audio urls. | ||
* @param {boolean} [free = false] Pass true to release only free audio nodes. | ||
* @return {Engine} | ||
*/ | ||
unloadMedia(urls) { | ||
unloadMedia(urls, free = false) { | ||
if (urls) { | ||
this._mediaLoader.unload(urls); | ||
this._mediaLoader.unload(urls, free); | ||
return this; | ||
} | ||
this._mediaLoader.unload(); | ||
this._mediaLoader.unload(null, free); | ||
@@ -369,3 +370,3 @@ return this; | ||
/** | ||
* Releases the allocated audio node for the group. | ||
* Releases the allocated audio nodes for the group. | ||
* @param {string} url The audio file url. | ||
@@ -382,11 +383,9 @@ * @param {number} groupId The group id. | ||
/** | ||
* Unallocates the audio node reserved for sound. | ||
* Releases the audio node reserved for sound. | ||
* @param {string} src The audio file url. | ||
* @param {number} groupId The buzz id. | ||
* @param {number} soundId The sound id. | ||
* @return {Engine} | ||
*/ | ||
releaseForSound(src, groupId, soundId) { | ||
this._mediaLoader.releaseForSound(src, groupId, soundId); | ||
return this; | ||
} | ||
@@ -405,12 +404,2 @@ | ||
/** | ||
* Destroys the audio node reserved for sound. | ||
* @param {string} src The audio file url. | ||
* @param {number} groupId The buzz id. | ||
* @param {number} soundId The sound id. | ||
*/ | ||
destroyAllocatedAudio(src, groupId, soundId) { | ||
this._mediaLoader.destroyAllocatedAudio(src, groupId, soundId); | ||
} | ||
/** | ||
* Mutes the engine. | ||
@@ -417,0 +406,0 @@ * @return {Engine} |
@@ -10,3 +10,3 @@ import utility from './Utility'; | ||
/** | ||
* Maximum number of audio nodes allowed for a url. | ||
* Maximum number of HTML5 audio nodes that can be allocated for a resource. | ||
* @type {number} | ||
@@ -40,3 +40,3 @@ * @private | ||
* Constructor | ||
* @param {number} maxNodesPerSource Maximum number of audio nodes allowed for a url. | ||
* @param {number} maxNodesPerSource Maximum number of audio nodes allowed for a resource. | ||
* @param {Heap} heap The sounds store. | ||
@@ -50,3 +50,3 @@ */ | ||
/** | ||
* Allocates an audio node for particular source. | ||
* Allocates an audio node for the passed source. | ||
* @param {string} src The audio url. | ||
@@ -115,6 +115,15 @@ * @return {Audio} | ||
/** | ||
* Releases all the audio nodes created for a resource. | ||
* Releases the audio nodes allocated for all resources. | ||
* @param {boolean} [free = false] Pass true to release only free audio nodes. | ||
*/ | ||
release(free = false) { | ||
Object.keys(this._resourceNodesMap).forEach(src => this.releaseForSource(src, free)); | ||
} | ||
/** | ||
* Releases the audio nodes allocated for a resource. | ||
* @param {string} src The audio url. | ||
* @param {boolean} [free = false] Pass true to release only free audio nodes. | ||
*/ | ||
releaseForSource(src) { | ||
releaseForSource(src, free = false) { | ||
const nodes = this._resourceNodesMap[src], | ||
@@ -125,6 +134,3 @@ { unallocated, allocated } = nodes; | ||
Object.keys(allocated).forEach(groupId => { | ||
allocated[groupId].forEach(x => this._destroyNode(x.audio)); | ||
delete allocated[groupId]; | ||
}); | ||
Object.keys(allocated).forEach(groupId => this.releaseForGroup(src, groupId, free)); | ||
@@ -135,3 +141,3 @@ delete this._resourceNodesMap[src]; | ||
/** | ||
* Releases all the audio nodes allocated for a group. | ||
* Releases the audio nodes allocated for a group. | ||
* @param {string} src The audio file url. | ||
@@ -152,46 +158,9 @@ * @param {number} groupId The group id. | ||
const audioNodes = allocated[groupId].filter(x => x.soundId === null).map(x => x.audio); | ||
// We can't reuse the audio node bcoz of this issue | ||
// https://github.com/WebAudio/web-audio-api/issues/1202. | ||
audioNodes.forEach(node => this._destroyNode(node)); | ||
allocated[groupId] = allocated[groupId].filter(x => x.soundId !== null); | ||
// nodes.unallocated = [...unallocated, ...audioNodes]; https://github.com/WebAudio/web-audio-api/issues/1202 | ||
audioNodes.forEach(node => this._destroyNode(node)); | ||
} | ||
/** | ||
* Release the audio element that is allocated for the sound. | ||
* @param {string} src The audio file url. | ||
* @param {number} groupId The group id. | ||
* @param {number} soundId The sound id. | ||
*/ | ||
releaseForSound(src, groupId, soundId) { | ||
const nodes = this._resourceNodesMap[src], | ||
{ unallocated, allocated } = nodes; | ||
const allocatedAudioObj = allocated[groupId].find(x => x.soundId === soundId); | ||
if (!allocatedAudioObj) { | ||
return; | ||
} | ||
allocated[groupId] = allocated[groupId].filter(x => x.soundId !== soundId); | ||
nodes.unallocated = [...unallocated, allocatedAudioObj.audio]; | ||
} | ||
/** | ||
* Returns if there are free audio nodes available for a group. | ||
* @param {string} src The audio file url. | ||
* @param {number} groupId The group id. | ||
* @return {boolean} | ||
*/ | ||
hasFreeNodes(src, groupId) { | ||
if (!this._resourceNodesMap.hasOwnProperty(src)) { | ||
return false; | ||
} | ||
const nodes = this._resourceNodesMap[src], | ||
{ allocated } = nodes; | ||
const unallocatedObjects = allocated[groupId].filter(x => x.soundId === null); | ||
return unallocatedObjects.length > 0; | ||
} | ||
/** | ||
* Destroys the audio node reserved for sound. | ||
@@ -202,3 +171,3 @@ * @param {string} src The audio file url. | ||
*/ | ||
destroyAllocatedAudio(src, soundIdOrAudio, groupId) { | ||
releaseForSound(src, soundIdOrAudio, groupId) { | ||
const nodes = this._resourceNodesMap[src], | ||
@@ -253,2 +222,20 @@ { allocated, unallocated } = nodes; | ||
/** | ||
* Returns true if there are free audio nodes available for a group. | ||
* @param {string} src The audio file url. | ||
* @param {number} groupId The group id. | ||
* @return {boolean} | ||
*/ | ||
hasFreeNodes(src, groupId) { | ||
if (!this._resourceNodesMap.hasOwnProperty(src)) { | ||
return false; | ||
} | ||
const nodes = this._resourceNodesMap[src], | ||
{ allocated } = nodes; | ||
const unallocatedObjects = allocated[groupId].filter(x => x.soundId === null); | ||
return unallocatedObjects.length > 0; | ||
} | ||
/** | ||
* Creates an entry for the passed source in object if not exists. | ||
@@ -255,0 +242,0 @@ * @param {string} src The audio file. |
@@ -55,3 +55,3 @@ import Html5AudioPool from './Html5AudioPool'; | ||
/** | ||
* Loads audio node for group. | ||
* Allocates audio node for a group. | ||
* @param {string} url The audio file url. | ||
@@ -77,6 +77,7 @@ * @param {number} groupId The group id. | ||
/** | ||
* Releases the allocated audio node(s). | ||
* Releases the allocated audio node(s) for the passed urls. | ||
* @param {string|string[]} [urls] Single or array of audio file urls. | ||
* @param {boolean} [free = false] Pass true to release only free audio nodes. | ||
*/ | ||
unload(urls) { | ||
unload(urls, free = false) { | ||
const removeAudioObjOfUrl = url => { | ||
@@ -89,13 +90,16 @@ const audioObj = this._bufferingAudios.find(a => a.url === url); | ||
this._bufferingAudios.forEach(audioObj => this._cleanUp(audioObj)); | ||
this._audioPool.release(free); | ||
} else if (typeof urls === 'string') { | ||
removeAudioObjOfUrl(urls); | ||
this._audioPool.releaseForSource(urls, free); | ||
} else if (Array.isArray(urls) && urls.length) { | ||
urls.forEach(url => removeAudioObjOfUrl(url)); | ||
urls.forEach(url => { | ||
removeAudioObjOfUrl(url); | ||
this._audioPool.releaseForSource(url, free); | ||
}); | ||
} | ||
urls.forEach(url => this._audioPool.releaseForSource(url)); | ||
} | ||
/** | ||
* Releases the allocated audio node for the group. | ||
* Releases the allocated audio node for the passed group. | ||
* @param {string} url The audio file url. | ||
@@ -114,3 +118,3 @@ * @param {number} groupId The group id. | ||
/** | ||
* Unallocates the audio node reserved for sound. | ||
* Destroys the audio node reserved for sound. | ||
* @param {string} src The audio file url. | ||
@@ -135,12 +139,2 @@ * @param {number} groupId The buzz id. | ||
/** | ||
* Destroys the audio node reserved for sound. | ||
* @param {string} src The audio file url. | ||
* @param {number} groupId The buzz id. | ||
* @param {number} soundId The sound id. | ||
*/ | ||
destroyAllocatedAudio(src, groupId, soundId) { | ||
this._audioPool.destroyAllocatedAudio(src, groupId, soundId); | ||
} | ||
/** | ||
* Acquires the unallocated audio nodes and removes the excess ones. | ||
@@ -195,3 +189,3 @@ */ | ||
audioObj && this._cleanUp(audioObj); | ||
this._audioPool.destroyAllocatedAudio(url, audio, groupId); | ||
this._audioPool.releaseForSound(url, audio, groupId); | ||
resolve(new DownloadResult(url, null, err)); | ||
@@ -198,0 +192,0 @@ }; |
@@ -255,2 +255,7 @@ import engine from './Engine'; | ||
constructor(args) { | ||
this._onBufferEnded = this._onBufferEnded.bind(this); | ||
this._onHtml5Ended = this._onHtml5Ended.bind(this); | ||
this._onCanPlayThrough = this._onCanPlayThrough.bind(this); | ||
this._onAudioError = this._onAudioError.bind(this); | ||
const { | ||
@@ -318,5 +323,2 @@ id, | ||
} | ||
this._onBufferEnded = this._onBufferEnded.bind(this); | ||
this._onHtml5Ended = this._onHtml5Ended.bind(this); | ||
} | ||
@@ -332,12 +334,7 @@ | ||
const onCanPlayThrough = () => { | ||
this._loadCallback(); | ||
this._audio.removeEventListener('canplaythrough', onCanPlayThrough); | ||
}; | ||
this._audio.addEventListener('canplaythrough', onCanPlayThrough); | ||
this._audio.addEventListener('canplaythrough', this._onCanPlayThrough); | ||
this._audio.currentTime = 0; | ||
if (this._audio.readyState >= 3) { | ||
onCanPlayThrough(); | ||
this._onCanPlayThrough(); | ||
} | ||
@@ -407,3 +404,3 @@ } | ||
if (this._stream) { | ||
this._audio.removeEventListener('ended', this._onEnded); | ||
this._audio.removeEventListener('ended', this._onHtml5Ended); | ||
this._clearEndTimer(); | ||
@@ -560,3 +557,3 @@ this._audio.pause(); | ||
let [, duration] = this._getTimeVars(); | ||
this._endTimer = workerTimer.setTimeout(this._onEnded, (duration * 1000) / Math.abs(rate)); | ||
this._endTimer = workerTimer.setTimeout(this._onHtml5Ended, (duration * 1000) / Math.abs(rate)); | ||
} | ||
@@ -639,9 +636,16 @@ } else { | ||
// Destroy the media element audio source node if it's there. | ||
this._destroyMediaSourceNode(); | ||
this._audio && this._audio.removeEventListener('error', this._onAudioError); | ||
// Remove audio event handlers. | ||
if (this._audio) { | ||
this._audio.removeEventListener('canplaythrough', this._onCanPlayThrough); | ||
this._audio.removeEventListener('error', this._onAudioError); | ||
} | ||
// Disconnect from the master gain. | ||
this._gainNode && this._gainNode.disconnect(); | ||
this._audio = null; | ||
this._buffer = null; | ||
this._audio = null; | ||
this._context = null; | ||
@@ -864,2 +868,11 @@ this._gainNode = null; | ||
/** | ||
* Event handler for audio's "canplaythrough" event. | ||
* @private | ||
*/ | ||
_onCanPlayThrough() { | ||
this._loadCallback(); | ||
this._audio.removeEventListener('canplaythrough', this._onCanPlayThrough); | ||
}; | ||
/** | ||
* Returns the gain node. | ||
@@ -866,0 +879,0 @@ * @return {GainNode} |
@@ -29,3 +29,3 @@ import webpack from 'webpack'; | ||
`/*! | ||
* musquito v2.0.1 | ||
* musquito v2.0.2 | ||
* http://musquitojs.com | ||
@@ -32,0 +32,0 @@ * |
4352155
4578