/*
* Copyright (C) 2012-2013 DFKI GmbH
* Deutsches Forschungszentrum fuer Kuenstliche Intelligenz
* German Research Center for Artificial Intelligence
* http://www.dfki.de
*
* 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.
*/
newMediaPlugin = {
/** @memberOf CordovaAudioOutput# */
initialize: function(callBack, mediaManager){
/** @memberOf CordovaAudioOutput# */
var _pluginName = 'codovaAudioOutput';
//invoke the passed-in initializer-callback and export the public functions:
callBack({
/**
* @public
* @memberOf CordovaAudioOutput.prototype
* @see mmir.MediaManager#playWAV
*/
playWAV: function(blob, successCallback, failureCallback){
try {
var blobURL = window.URL.createObjectURL(blob);
var my_media = new Media(
blobURL,
function(){
// console.log('WAV Audio created');
my_media.release();
if(successCallback){
successCallback();
}
},failureCallback
);
my_media.play();
} catch (e){
if(failureCallback){
failureCallback(e);
}
}
},
/**
* @public
* @memberOf CordovaAudioOutput.prototype
* @see mmir.MediaManager#playURL
*/
playURL: function(url, successCallback, failureCallback){
try {
// console.log(url);
var my_media = new Media(
url,
function(){
// console.log('Audio played');
my_media.release();
if(successCallback){
successCallback.apply(my_media,arguments);
}
} ,
failureCallback
);
my_media.play();
} catch (e){
if(failureCallback){
failureCallback.apply(my_media,arguments);
}
}
},
/**
* @public
* @type Function
* @memberOf CordovaAudioOutput.prototype
* @see mmir.MediaManager#play
*/
play: mediaManager.play,
/**
* @public
* @memberOf CordovaAudioOutput.prototype
* @see mmir.MediaManager#getURLAsAudio
*/
getURLAsAudio: function(url, onEnd, failureCallback, onCanPlay){
try {
/**
* @private
* @memberOf AudioCordovaImpl#
*/
var playStatus = 0;
/**
* @private
* @memberOf AudioCordovaImpl#
*/
var my_media = new Media(
url
,null //DEBUG: function(){console.log('native onReady CB');}
,failureCallback
,function(status){
// console.debug("media status change "+playStatus+" -> "+status+" for: "+url);
playStatus = status;
if (status==1){
if (onCanPlay){
onCanPlay.apply(mediaImpl, arguments);
onCanPlay = null;//remove onCanPlay callback after first invocation
}
}
// else if (status==2){
// console.log("Audio started");
// }
// else if (status==3){
// console.log("Audio paused");
// }
else if(status == 4){
if (onEnd){
onEnd.apply(mediaImpl, arguments);
}
}
}
);
/**
* @private
* @memberOf AudioCordovaImpl#
*/
var enabled = true;
/**
* The Audio abstraction that is returned by {@link mmir.MediaManager#getURLAsAudio}.
*
* <p>
* NOTE: when an audio object is not used anymore, its {@link #release} method should
* be called.
*
* <p>
* This is the same interface as {@link mmir.env.media.AudioHtml5Impl}.
*
* @class
* @name AudioCordovaImpl
* @memberOf mmir.env.media
* @implements mmir.env.media.IAudio
* @public
*/
var mediaImpl = {
/**
* Play audio.
*
* @inheritdoc
* @name play
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
play: function(){
if (enabled){
my_media.play();
return playStatus >= 1;
}
return false;
},
/**
* Stop playing audio.
*
* @inheritdoc
* @name stop
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
stop: function(){
//use "manual" stop instead of Cordova's stop
//in order to allow "forgiving" behavior when audio is already stopped
// -> Cordova's stop() requires the audio to be playing, otherwise an error is thrown/triggered
// console.info('CordovaAudio.stop[state '+playStatus
// +', duration '+my_media.duration
// +', position '+my_media.position
//// +', currentPosition '+my_media.getCurrentPosition()
// +']: '+url);
//only try to stop if playing and/or paused
if(playStatus == 2 || playStatus == 3){
my_media.stop();
return true;
}
// if(playStatus == 2){//playing
// my_media.stop();
// }
// else if(playStatus == 3){//paused
// my_media.seekTo(0);
// }
//// my_media.stop();
return playStatus === 4;
},
/**
* Enable audio (should only be used internally).
*
* @inheritdoc
* @name enable
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
enable: function(){
enabled = true;
},
/**
* Disable audio (should only be used internally).
*
* @inheritdoc
* @name disable
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
disable: function(){
if(enabled){
this.stop();
enabled = false;
}
},
/**
* Release audio: should be called when the audio
* file is not used any more.
*
* NOTE Android has limited resources available - not releasing resources
* may result in not being able to instantiate new (audio) resources.
*
* @inheritdoc
* @name release
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
release: function(){
if(enabled && ! this.isPaused()){
this.stop();
}
enabled= false;
if(my_media){
my_media.release();
}
},
/**
* Set the volume of this audio file
*
* @param {Number} value
* the new value for the volume:
* a number between [0.0, 1.0]
*
* @inheritdoc
* @name setVolume
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
setVolume: function(value){
if(my_media){
my_media.setVolume(value);
}
},
/**
* Get the duration of the audio file
*
* @returns {Number} the duration in MS (or -1 if unknown)
*
* @inheritdoc
* @name getDuration
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
getDuration: function(){
if(my_media){
return my_media.duration;
}
return -1;
},
/**
* Check if audio is currently paused.
*
* NOTE: "paused" is a different status than "stopped".
*
* @returns {Boolean} TRUE if paused, FALSE otherwise
*
* @inheritdoc
* @name isPaused
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
isPaused: function(){
if(my_media){
return playStatus == 3;
}
return false;
},
/**
* Check if audio is currently enabled
*
* @returns {Boolean} TRUE if enabled
*
* @inheritdoc
* @name isEnabled
* @memberOf mmir.env.media.AudioCordovaImpl.prototype
*/
isEnabled: function(){
return enabled;
}
};
//WORK-AROUND for Android: need to invoke a method on the Media object in
// order to trigger the on-init callback.
my_media.seekTo(0);
return mediaImpl;
} catch (e){
console.error(e);
if(failureCallback){
failureCallback(e);
}
}
},//END: getURLAsAudio
/**
* @public
* @type Function
* @memberOf CordovaAudioOutput.prototype
* @see mmir.MediaManager#getAudio
*/
getAudio: function(url, onPlayedCallback, failureCallBack, onLoadedCallBack){
if(typeof url !== 'string'){
mediaManager._log.error(_pluginName+'.getAudio(): getWAVAsAudio is not supported by this module.');
} else {
return this.getURLAsAudio.apply(this, arguments);
}
}
});//END: callBack({...
}
};