Friday, 10 August 2012

Native HTM5 Audio for Cross-Platform Lazy

I've been using WebViews to handle the multiplayer code in my games Phone Wars and Food Fighters. Yes, I know it sounds a bit silly, but it does give you some nice little bonuses like being able to update the code without pushing an app update and being able to easily communicate with webapps.

The next challenge I set this reverse PhoneGap methodology was to get our game background music running with an HTML5 audio tag.
(Quick justification as to why you'd want to do this would be to be able to change the music on the fly without having to release an app update).

To set this up, you just create an Audio object, set it to loop and fire play..
 var muisc = new Audio( "song.mp3" );  
 music.loop = true;  
 music.play();  

Well this might work in a web browser, however in WebViews on mobiles, it's not so straight forward.

Firstly on iOS, you need to disable mediaplayback requiring a user action.
 self.allowsInlineMediaPlayback = true;  
 self.mediaPlaybackRequiresUserAction = false;  

Ok, that was easy enough.

Android however, well, it's a bit more interesting. On some versions of Android I've tested, the audio doesn't loop and on some the audio does loop. To combat this, I tried setting the currentTime to 0, and re-playing the audio when the ended event gets fired.
 music.addEventListener( 'ended', function()   
           {  
             this.currentTime = 0;  
             this.play();  
           }, false);  
Again, this seemed to not work on some versions of Android.

After hours of trying various methods, it seemed the issue boiled down to currentTime not being set on some devices. To combat this, what I ended up doing was re-creating the audio when the audio finished.
 var music = false;  
function playMusic()  
{  
     music = new Audio( "song.mp3" );  
     music.addEventListener( 'ended', function()   
     {  
         playMusic();  
     }, false);   
     music.play();  
}  
playMusic();  

Perfect, we now have a looping audio track.

Problem? Well, when you exit your Android app, the music still loops in the background. By default your WebView still churns on in the background even when your application closes. This too occurs on iOS, however, on iOS while other operations may still fire in the WebKit process, the music gets killed.

Well ok, just make sure you turn off the audio when your application gets paused and you're done?

Almost.. If your application uses GCM push notifications.. you may have problems.
See the video below.


To be continued..