问题
In my app i have given sound response on mouse click. This is how i have done
i have called the function like this
<center><input id="click_flip" type="button" value="Click Me" class="clickme" onclick="callplay()"></center>
here is the function
<script type="text/javascript" charset="utf-8">
function callplay()
{
if(voice=="male")
playAudio('/android_asset/www/Mobile/sound/Male/'+rand1+'.mp3');
else
playAudio('/android_asset/www/Mobile/sound/Female/'+rand1+'.mp3');
}
// Audio player
//
var my_media = null;
// Play audio
//
function playAudio(src) {
// Create Media object from src
my_media = new Media(src, onSuccess, onError);
// else play current audio
// Play audio
my_media.play();
}
// onSuccess Callback
//
function onSuccess() {
console.log("playAudio():Audio Success");
}
// onError Callback
//
function onError(error) {
// alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
</script>
But when i am repeating the button click multiple (around 30 to 40 ) times. The sound is not giving any responses.
After that using this link i have added this function
if(my_media){
my_media.stop();
my_media.release();
}
also tried this
function playAudio(url) {
try {
var my_media = new Media(url,
// success callback
function () {
**my_media.release();**
},
// error callback
function (err) {
**my_media.release();**
});
// Play audio
my_media.play();
} catch (e) {
alert(e.message);
}
}
but not working. Please suggest
回答1:
I have the same problem, now I try to use this way and it seems working:
var my_media = null;
function playAudio(src)
{
if(my_media != null) my_media.release();
my_media = new Media(src);
my_media.play();
}
If you release the hardware you dont need to stop, because the release automatic stop the current media in android. Somehow if you try release in the success or in the error callback it does not always work. There are times when I try to play when the Media is not finished yet and this break the Media object.
回答2:
In My case i have scanning app with phone gap. and it vibrates and beep fail when scan fails via our API scanning ticket. and there is success sound without vibration via our API scanning ticket.
After 35 to 40 times it fails to either vibrate or play sound.
Code Before Fix:
In HTML
<audio id="successSound"
src="/android_asset/www/audio/correct.mp3"
type="audio/mpeg">
</audio>
var my_media = null;
var mediaTimer = null;
function playAudio(id) {
var audioElement = document.getElementById(id);
var src = audioElement.getAttribute('src');
// Create Media object from src
// alert(src);
// alert(getPathMedia());
my_media = new Media(src, onSuccess, onError);
// Play audio
my_media.play();
// Update my_media position every second
if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition((position) + " sec");
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}
}
// Pause audio
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
function stopAudio() {
if (my_media) {
my_media.stop();
}
clearInterval(mediaTimer);
mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess() {
// alert('success');
}
// onError Callback
function onError(error) {
switch(error.code){
case MediaError.MEDIA_ERR_ABORTED:
alert('MEDIA_ERR_ABORTED code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NETWORK:
alert('MEDIA_ERR_NETWORK code: ' + error.code);
break;
case MediaError.MEDIA_ERR_DECODE:
alert('MEDIA_ERR_DECODE code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NONE_SUPPORTED:
alert('MEDIA_ERR_NONE_SUPPORTED code: ' + error.code);
break;
default:
{
alert('Un Known: ' + error.code);
navigator.notification.vibrate(2000);
playAudio("errorSound");
}
}
}
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
Code After Fix:
var failCounter = 0;
var successCounter = 0;
var srcSuccess = "/android_asset/www/audio/correct.mp3";
var srcFail = "/android_asset/www/audio/error_long.mp3";
var my_media_success = null;
var my_media_fail = null;
function playAudioSuccess() {
// stopAudio(my_media);
if (my_media_success != null) {
my_media_success.release();
}
successCounter = successCounter + 1;
// Create Media object from src
// alert(src);
// alert(getPathMedia());
try {
my_media_success = new Media(srcSuccess, onSuccess, onError);
// my_media.setVolume('1.0');
// if (successCounter >= 35) {
// alert("success count " + successCounter + " total counting " + ( successCounter + failCounter));
// }
// Play audio
my_media_success.play();
} catch (err) {
alert(err);
}
}
function playAudioFail() {
try {
// stopAudio(my_media);
if (my_media_fail != null) {
my_media_fail.release();
}
failCounter = failCounter + 1;
// Create Media object from src
// alert(src);
// alert(getPathMedia());
my_media_fail = new Media(srcFail, onSuccess, onError);
// my_media_fail.setVolume('1.0');
// if (failCounter >= 35) {
// alert("fail count " + failCounter + " total counting " + ( successCounter + failCounter));
// }
// Play audio
my_media_fail.play();
} catch (err) {
alert(err);
}
}
// Pause audio
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
function stopAudio(my_media) {
if (my_media) {
my_media.stop();
}
// clearInterval(mediaTimer);
// mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess() {
// alert('success');
}
// onError Callback
function onError(error) {
switch(error.code){
case MediaError.MEDIA_ERR_ABORTED:
alert('MEDIA_ERR_ABORTED code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NETWORK:
alert('MEDIA_ERR_NETWORK code: ' + error.code);
break;
case MediaError.MEDIA_ERR_DECODE:
alert('MEDIA_ERR_DECODE code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NONE_SUPPORTED:
alert('MEDIA_ERR_NONE_SUPPORTED code: ' + error.code);
break;
default:
{
alert('Un Known: ' + error.code);
navigator.notification.vibrate(1000);
setTimeout(function() {
playAudioFail();
}, delayInMilliseconds);
}
}
}
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
After lot of try and error and alerts here and there !
1) I avoided getElementById
to get the src path i just defined it as global variable.
2) I separated the methods of success and fail ( refactoring )
3) I made the variables local as much as possible to avoid any memory leaks and overlapping and exceed stack etc.. stuff.
4) I removed the setAudioPosition
method because its not used and called without a reason.
( lesson learned) when you take your code from internet be carefull of what you really need.
5) I noticed when i added alerts it worked but when i removed them it did not work , so my
MAIN SOLUTION was adding Timeoutbetween vibrate which is called first , and the play method at critical section like this
navigator.notification.vibrate(1000);
setTimeout(function() {
playAudioFail();
}, delayInMilliseconds);
6) I added release method , but
(leasson learned) be aware where to put it so I put it before calling the play it self on correct reference to same variable ofcourse.
if (my_media_fail != null) {
my_media_fail.release();
}
7) Last advice as its javascript you can use try and catch just in case )) Try catch W3School
来源:https://stackoverflow.com/questions/22731364/phonegap-sound-stops-playing-after-calling-playaudio-30-to-40-times