I'm working on a simple application that acts - a bit - like a sound board. You select an item, click a button, and you hear an MP3. While letting one of my kids play with it, they quickly discovered that if they hit the button multiple times in a row, the sound would play multiple times, overlapping each other. While not the end of the world (this is the kind of bug that would only occur if the user was trying to do exactly that), I thought I should probably prevent this from happening.
Here's the original method:
$scope.play = function(mp3) {
mp3 = "data/mp3/" + mp3;
if(device.platform.toLowerCase() === "android") mp3 = "/android_asset/www/" + mp3;
if(window.Media) {
var media = new Media(mp3, null, function(err) {
alert(JSON.stringify(err));
});
media.play();
}
};
If you read the docs for the media plugin, you will discover that there are multiple ways to know when a Media object is done playing. In theory, I could use that to determine when it is safe for a new MP3 to play. But why go complex when you use simpler logic? How about simply seeing if the media variable is instantiated and call stop()? Calling stop is harmless if the sound is already done and it quickly handles the issue with one line of code (well, one line and one small mod).
I moved my media variable outside the function and updated my function like so:
var media;
$scope.play = function(mp3) {
mp3 = "data/mp3/" + mp3;
if(device.platform.toLowerCase() === "android") mp3 = "/android_asset/www/" + mp3;
if(window.Media) {
if(media) media.stop();
media = new Media(mp3, null, function(err) {
alert(JSON.stringify(err));
});
media.play();
}
};
And that's that. Now if you click the button like crazy, the previous sound stops before starting up again.
Archived Comments
Hey I working on a music app using cordova and I think before stopping the media object you should check the status of the media you want to stop(on android at least) . If the status of the media object is not 1, 2 ,3 or 4 . The stop call will fail. You have to wait for the status to change to one those value before you can stop it . Just something to keep in mind :)
But how does it fail? Is an exception logged or does nothing happen?
Hey Raymond, I did some testing over the weekend and It looks like the error was showing because I was calling the stop before coming play which sounds like the expected behavior. My bad . I will just delete my comment then :)