/bower_components/SoundJS/lib/cordovaaudioplugin-0.6.2.combined.js |
@@ -0,0 +1,570 @@ |
/*! |
* SoundJS |
* Visit http://createjs.com/ for documentation, updates and examples. |
* |
* Copyright (c) 2010 gskinner.com, inc. |
* |
* Permission is hereby granted, free of charge, to any person |
* obtaining a copy of this software and associated documentation |
* files (the "Software"), to deal in the Software without |
* restriction, including without limitation the rights to use, |
* copy, modify, merge, publish, distribute, sublicense, and/or sell |
* copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following |
* conditions: |
* |
* The above copyright notice and this permission notice shall be |
* included in all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
* OTHER DEALINGS IN THE SOFTWARE. |
*/ |
|
|
//############################################################################## |
// CordovaAudioLoader.js |
//############################################################################## |
|
this.createjs = this.createjs || {}; |
|
(function () { |
"use strict"; |
|
/** |
* Loader provides a mechanism to preload Cordova audio content via PreloadJS or internally. Instances are returned to |
* the preloader, and the load method is called when the asset needs to be requested. |
* Currently files are assumed to be local and no loading actually takes place. This class exists to more easily support |
* the existing architecture. |
* |
* @class CordovaAudioLoader |
* @param {String} loadItem The item to be loaded |
* @extends XHRRequest |
* @protected |
*/ |
function Loader(loadItem) { |
this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.SOUND); |
|
/** |
* A Media object used to determine if src exists and to get duration |
* @property _media |
* @type {Media} |
* @protected |
*/ |
this._media = null; |
|
/** |
* A time counter that triggers timeout if loading takes too long |
* @property _loadTime |
* @type {number} |
* @protected |
*/ |
this._loadTime = 0; |
|
/** |
* The frequency to fire the loading timer until duration can be retrieved |
* @property _TIMER_FREQUENCY |
* @type {number} |
* @protected |
*/ |
this._TIMER_FREQUENCY = 100; |
}; |
var p = createjs.extend(Loader, createjs.AbstractLoader); |
|
|
// public methods |
p.load = function() { |
this._media = new Media(this._item.src, null, createjs.proxy(this._mediaErrorHandler,this)); |
this._media.seekTo(0); // needed to get duration |
|
this._getMediaDuration(); |
}; |
|
p.toString = function () { |
return "[CordovaAudioLoader]"; |
}; |
|
|
// private methods |
/** |
* Fires if audio cannot seek, indicating that src does not exist. |
* @method _mediaErrorHandler |
* @param error |
* @protected |
*/ |
p._mediaErrorHandler = function(error) { |
this._media.release(); |
this._sendError(); |
}; |
|
/** |
* will attempt to get duration of audio until successful or time passes this._item.loadTimeout |
* @method _getMediaDuration |
* @protected |
*/ |
p._getMediaDuration = function() { |
this._result = this._media.getDuration() * 1000; |
if (this._result < 0) { |
this._loadTime += this._TIMER_FREQUENCY; |
if (this._loadTime > this._item.loadTimeout) { |
this.handleEvent({type:"timeout"}); |
} else { |
setTimeout(createjs.proxy(this._getMediaDuration, this), this._TIMER_FREQUENCY); |
} |
} else { |
this._media.release(); |
this._sendComplete(); |
} |
}; |
|
createjs.CordovaAudioLoader = createjs.promote(Loader, "AbstractLoader"); |
}()); |
|
//############################################################################## |
// CordovaAudioSoundInstance.js |
//############################################################################## |
|
this.createjs = this.createjs || {}; |
|
(function () { |
"use strict"; |
|
/** |
* CordovaAudioSoundInstance extends the base api of {{#crossLink "AbstractSoundInstance"}}{{/crossLink}} and is used by |
* {{#crossLink "CordovaAudioPlugin"}}{{/crossLink}}. |
* |
* @param {String} src The path to and file name of the sound. |
* @param {Number} startTime Audio sprite property used to apply an offset, in milliseconds. |
* @param {Number} duration Audio sprite property used to set the time the clip plays for, in milliseconds. |
* @param {Object} playbackResource Any resource needed by plugin to support audio playback. |
* @class CordovaAudioSoundInstance |
* @extends AbstractSoundInstance |
* @constructor |
*/ |
function CordovaAudioSoundInstance(src, startTime, duration, playbackResource) { |
this.AbstractSoundInstance_constructor(src, startTime, duration, playbackResource); |
|
// Public Properties |
/** |
* Sets the playAudioWhenScreenIsLocked property for play calls on iOS devices. |
* @property playWhenScreenLocked |
* @type {boolean} |
*/ |
this.playWhenScreenLocked = null; |
|
// Private Properties |
/** |
* Used to approximate the playback position by storing the number of milliseconds elapsed since |
* 1 January 1970 00:00:00 UTC when playing |
* Note that if js clock is out of sync with Media playback, this will become increasingly inaccurate. |
* @property _playStartTime |
* @type {Number} |
* @protected |
*/ |
this._playStartTime = null; |
|
/** |
* A TimeOut used to trigger the end and possible loop of audio sprites. |
* @property _audioSpriteTimeout |
* @type {null} |
* @protected |
*/ |
this._audioSpriteTimeout = null; |
|
/** |
* Boolean value that indicates if we are using an audioSprite |
* @property _audioSprite |
* @type {boolean} |
* @protected |
*/ |
this._audioSprite = false; |
|
// Proxies, make removing listeners easier. |
this._audioSpriteEndHandler = createjs.proxy(this._handleAudioSpriteComplete, this); |
this._mediaPlayFinishedHandler = createjs.proxy(this._handleSoundComplete, this); |
this._mediaErrorHandler = createjs.proxy(this._handleMediaError, this); |
this._mediaProgressHandler = createjs.proxy(this._handleMediaProgress, this); |
|
this._playbackResource = new Media(src, this._mediaPlayFinishedHandler, this._mediaErrorHandler, this._mediaProgressHandler); |
|
if (duration) { |
this._audioSprite = true; |
} else { |
this._setDurationFromSource(); |
} |
} |
var p = createjs.extend(CordovaAudioSoundInstance, createjs.AbstractSoundInstance); |
|
|
// Public Methods |
/** |
* Called by {{#crossLink "Sound"}}{{/crossLink}} when plugin does not handle master volume. |
* undoc'd because it is not meant to be used outside of Sound |
* #method setMasterVolume |
* @param value |
*/ |
p.setMasterVolume = function (value) { |
this._updateVolume(); |
}; |
|
/** |
* Called by {{#crossLink "Sound"}}{{/crossLink}} when plugin does not handle master mute. |
* undoc'd because it is not meant to be used outside of Sound |
* #method setMasterMute |
* @param value |
*/ |
p.setMasterMute = function (isMuted) { |
this._updateVolume(); |
}; |
|
p.destroy = function() { |
// call parent function, then release |
this.AbstractSoundInstance_destroy(); |
this._playbackResource.release(); |
}; |
|
/** |
* Maps to <a href="http://plugins.cordova.io/#/package/org.apache.cordova.media" target="_blank">Media.getCurrentPosition</a>, |
* which is curiously asynchronus and requires a callback. |
* @method getCurrentPosition |
* @param {Method} mediaSuccess The callback that is passed the current position in seconds. |
* @param {Method} [mediaError=null] (Optional) The callback to execute if an error occurs. |
*/ |
p.getCurrentPosition = function (mediaSuccess, mediaError) { |
this._playbackResource.getCurrentPosition(mediaSuccess, mediaError); |
}; |
|
p.toString = function () { |
return "[CordovaAudioSoundInstance]"; |
}; |
|
//Private Methods |
/** |
* media object has failed and likely will never work |
* @method _handleMediaError |
* @param error |
* @private |
*/ |
p._handleMediaError = function(error) { |
clearTimeout(this.delayTimeoutId); // clear timeout that plays delayed sound |
|
this.playState = createjs.Sound.PLAY_FAILED; |
this._sendEvent("failed"); |
}; |
|
p._handleMediaProgress = function(state) { |
// do nothing |
}; |
|
p._handleAudioSpriteComplete = function() { |
this._playbackResource.pause(); |
this._handleSoundComplete(); |
}; |
/* don't need these for current looping approach |
p._removeLooping = function() { |
}; |
|
p._addLooping = function() { |
}; |
*/ |
|
p._handleCleanUp = function () { |
clearTimeout(this._audioSpriteTimeout); |
this._playbackResource.pause(); // OJR cannot use .stop as it prevents .seekTo from working |
// todo consider media.release |
}; |
|
p._handleSoundReady = function (event) { |
this._playbackResource.seekTo(this._startTime + this._position); |
|
if (this._audioSprite) { |
this._audioSpriteTimeout = setTimeout(this._audioSpriteEndHandler, this._duration - this._position) |
} |
|
this._playbackResource.play({playAudioWhenScreenIsLocked: this.playWhenScreenLocked}); |
this._playStartTime = Date.now(); |
}; |
|
p._pause = function () { |
clearTimeout(this._audioSpriteTimeout); |
this._playbackResource.pause(); |
if (this._playStartTime) { |
this._position = Date.now() - this._playStartTime; |
this._playStartTime = null; |
} |
this._playbackResource.getCurrentPosition(createjs.proxy(this._updatePausePos, this)); |
}; |
|
/** |
* Synchronizes the best guess position with the actual current position. |
* @method _updatePausePos |
* @param {Number} pos The current position in seconds |
* @private |
*/ |
p._updatePausePos = function (pos) { |
this._position = pos * 1000 - this._startTime; |
if(this._playStartTime) { |
this._playStartTime = Date.now(); |
} |
}; |
|
p._resume = function () { |
if (this._audioSprite) { |
this._audioSpriteTimeout = setTimeout(this._audioSpriteEndHandler, this._duration - this._position) |
} |
|
this._playbackResource.play({playAudioWhenScreenIsLocked: this.playWhenScreenLocked}); |
this._playStartTime = Date.now(); |
}; |
|
p._handleStop = function() { |
clearTimeout(this._audioSpriteTimeout); |
this._playbackResource.pause(); // cannot use .stop because it prevents .seekTo from working |
this._playbackResource.seekTo(this._startTime); |
if (this._playStartTime) { |
this._position = 0; |
this._playStartTime = null; |
} |
}; |
|
p._updateVolume = function () { |
var newVolume = (this._muted || createjs.Sound._masterMute) ? 0 : this._volume * createjs.Sound._masterVolume; |
this._playbackResource.setVolume(newVolume); |
}; |
|
p._calculateCurrentPosition = function() { |
// return best guess position. |
// Note if Media and js clock are out of sync, this value will become increasingly inaccurate over time |
if (this._playStartTime) { |
this._position = Date.now() - this._playStartTime + this._position; |
this._playStartTime = Date.now(); |
} |
return this._position; |
}; |
|
p._updatePosition = function() { |
this._playbackResource.seekTo(this._startTime + this._position); |
this._playStartTime = Date.now(); |
if (this._audioSprite) { |
clearTimeout(this._audioSpriteTimeout); |
this._audioSpriteTimeout = setTimeout(this._audioSpriteEndHandler, this._duration - this._position) |
} |
}; |
|
p._handleLoop = function (event) { |
this._handleSoundReady(); |
}; |
|
p._updateStartTime = function () { |
this._audioSprite = true; |
|
if(this.playState == createjs.Sound.PLAY_SUCCEEDED) { |
// do nothing |
} |
}; |
|
p._updateDuration = function () { |
this._audioSprite |
|
if(this.playState == createjs.Sound.PLAY_SUCCEEDED) { |
clearTimeout(this._audioSpriteTimeout); |
this._audioSpriteTimeout = setTimeout(this._audioSpriteEndHandler, this._duration - this.position) |
} |
}; |
|
p._setDurationFromSource = function () { |
this._duration = createjs.Sound.activePlugin.getSrcDuration(this.src); // TODO find a better way to do this that does not break flow |
}; |
|
createjs.CordovaAudioSoundInstance = createjs.promote(CordovaAudioSoundInstance, "AbstractSoundInstance"); |
}()); |
|
//############################################################################## |
// CordovaAudioPlugin.js |
//############################################################################## |
|
this.createjs = this.createjs || {}; |
|
(function () { |
|
"use strict"; |
|
/** |
* Play sounds using Cordova Media plugin, which will work with a Cordova app and tools that utilize Cordova such as PhoneGap or Ionic. |
* This plugin is not used by default, and must be registered manually in {{#crossLink "Sound"}}{{/crossLink}} |
* using the {{#crossLink "Sound/registerPlugins"}}{{/crossLink}} method. |
* This plugin is recommended when building a Cordova based app, but is not required. |
* |
* <b>NOTE the <a href="http://plugins.cordova.io/#/package/org.apache.cordova.media" target="_blank">Cordova Media plugin</a> is required</b> |
* |
* cordova plugin add org.apache.cordova.media |
* |
* <h4>Known Issues</h4> |
* <b>Audio Position</b> |
* <ul>Audio position is calculated asynchronusly by Media. The SoundJS solution to this problem is two-fold: |
* <li>Provide {{#crossLink "CordovaAudioSoundInstance/getCurrentPosition"}}{{/crossLink}} that maps directly to media.getCurrentPosition.</li> |
* <li>Provide a best guess position based on elapsed time since playback started, which is synchronized with actual position when the audio is paused or stopped. |
* Testing showed this to be fairly reliable within 200ms.</li></ul> |
* <b>Cordova Media Docs</b> |
* <ul><li>See the <a href="http://plugins.cordova.io/#/package/org.apache.cordova.media" target="_blank">Cordova Media Docs</a> for various known OS issues.</li></ul> |
* <br /> |
* |
* @class CordovaAudioPlugin |
* @extends AbstractPlugin |
* @constructor |
*/ |
function CordovaAudioPlugin() { |
this.AbstractPlugin_constructor(); |
|
this._capabilities = s._capabilities; |
|
this._loaderClass = createjs.CordovaAudioLoader; |
this._soundInstanceClass = createjs.CordovaAudioSoundInstance; |
|
this._srcDurationHash = {}; |
} |
|
var p = createjs.extend(CordovaAudioPlugin, createjs.AbstractPlugin); |
var s = CordovaAudioPlugin; |
|
|
// Static Properties |
/** |
* Sets a default playAudioWhenScreenIsLocked property for play calls on iOS devices. |
* Individual SoundInstances can alter the default with {{#crossLink "CordovaAudioSoundInstance/playWhenScreenLocked"}}{{/crossLink}}. |
* @property playWhenScreenLocked |
* @type {boolean} |
* @static |
*/ |
s.playWhenScreenLocked = false; |
|
/** |
* The capabilities of the plugin. This is generated via the {{#crossLink "CordovaAudioPlugin/_generateCapabilities"}}{{/crossLink}} |
* method. Please see the Sound {{#crossLink "Sound/getCapabilities"}}{{/crossLink}} method for an overview of all |
* of the available properties. |
* @property _capabilities |
* @type {Object} |
* @protected |
* @static |
*/ |
s._capabilities = null; |
|
|
// Static Methods |
/** |
* Determine if the plugin can be used in the current browser/OS. Note that HTML audio is available in most modern |
* browsers, but is disabled in iOS because of its limitations. |
* @method isSupported |
* @return {Boolean} If the plugin can be initialized. |
* @static |
*/ |
s.isSupported = function () { |
s._generateCapabilities(); |
return (s._capabilities != null); |
}; |
|
/** |
* Determine the capabilities of the plugin. Used internally. Please see the Sound API {{#crossLink "Sound/getCapabilities"}}{{/crossLink}} |
* method for an overview of plugin capabilities. |
* @method _generateCapabilities |
* @static |
* @protected |
*/ |
s._generateCapabilities = function () { |
if (s._capabilities != null || !(window.cordova || window.PhoneGap || window.phonegap) || !window.Media) {return;} |
|
// OJR my best guess is that Cordova will have the same limits on playback that the audio tag has, but this could be wrong |
var t = document.createElement("audio"); |
if (t.canPlayType == null) {return null;} |
|
s._capabilities = { |
panning:false, |
volume:true, |
tracks:-1 |
}; |
|
// determine which extensions our browser supports for this plugin by iterating through Sound.SUPPORTED_EXTENSIONS |
var supportedExtensions = createjs.Sound.SUPPORTED_EXTENSIONS; |
var extensionMap = createjs.Sound.EXTENSION_MAP; |
for (var i = 0, l = supportedExtensions.length; i < l; i++) { |
var ext = supportedExtensions[i]; |
var playType = extensionMap[ext] || ext; |
s._capabilities[ext] = (t.canPlayType("audio/" + ext) != "no" && t.canPlayType("audio/" + ext) != "") || (t.canPlayType("audio/" + playType) != "no" && t.canPlayType("audio/" + playType) != ""); |
} // OJR another way to do this might be canPlayType:"m4a", codex: mp4 |
}; |
|
|
// public methods |
p.create = function (src, startTime, duration) { |
var si = this.AbstractPlugin_create(src, startTime, duration); |
si.playWhenScreenLocked = this.playWhenScreenLocked; |
return si; |
}; |
|
p.toString = function () { |
return "[CordovaAudioPlugin]"; |
}; |
|
// plugin does not support these |
p.setVolume = p.getVolume = p.setMute = null; |
|
/** |
* Get the duration for a src. Intended for internal use by CordovaAudioSoundInstance. |
* @method getSrcDuration |
* @param src |
* @returns {Number} The duration of the src or null if it does not exist |
*/ |
p.getSrcDuration = function(src) { |
return this._srcDurationHash[src]; |
}; |
|
// Private Methods |
p._handlePreloadComplete = function (event) { |
var src = event.target.getItem().src; |
this._srcDurationHash[src] = event.result; |
this._audioSources[src] = event.result; |
//this.AbstractPlugin__handlePreloadComplete(event); // we don't want to do the rest of this |
}; |
|
p.removeSound = function (src) { |
delete(this._srcDurationHash[src]); |
this.AbstractPlugin_removeSound(src); |
}; |
|
createjs.CordovaAudioPlugin = createjs.promote(CordovaAudioPlugin, "AbstractPlugin"); |
}()); |
|
//############################################################################## |
// version_cordovaplugin.js |
//############################################################################## |
|
this.createjs = this.createjs || {}; |
|
(function () { |
|
var s = createjs.CordovaAudioPlugin = createjs.CordovaAudioPlugin || {}; |
|
/** |
* The version string for this release. |
* @for CordovaAudioPlugin |
* @property version |
* @type String |
* @static |
**/ |
s.version = /*=version*/"0.6.2"; // injected by build process |
|
/** |
* The build date for this release in UTC format. |
* @for CordovaAudioPlugin |
* @property buildDate |
* @type String |
* @static |
**/ |
s.buildDate = /*=date*/"Thu, 26 Nov 2015 20:44:31 GMT"; // injected by build process |
|
})(); |