4

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

Community
  • 1
  • 1
insanity
  • 1,148
  • 6
  • 16
  • 29

2 Answers2

1

I have the same problem, and made a workaround by releasing the previous media before creating a new one to play:

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 don't need to stop, because of the release automatically stops the current media. Somehow if you try to release in the success or in the error callback it does not always work.

There are times (especially with user inputs) when if you try to play a new media before the previous one is not finished, the whole thing just breaks.

adaliszk
  • 604
  • 5
  • 18
0

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

shareef
  • 9,255
  • 13
  • 58
  • 89