This tutorial is part of the SoundJS GitHub repository.
Check out the repository for more tutorials and a handful of helpful samples.
This tutorial will outline techniques for playing audio that work on the majority of devices and browsers, and specifically allows playback on mobile devices (phones/tablets) where security limitations often cause problems. It assumes you have read the Basics and Best Practices tutorial and uses the HTML built with it as a starting point. The end result will be similar to the MobileSafe.html example. Your starting html document should look like this:
A limitation that most mobile devices share is requiring media playback to be launched by a user initiated event, such as click, touch, or key press. Reportedly, this is to protect users from annoying sites and to prevent sites from automatically using bandwidth for users with limited data plans. If all you need to do is play audio in response to user interaction, then this is trivial. Just play each sound in a function that is triggered by user events.
For our first example, we'll play audio in direct response to a user initiated touch event. This is simple to execute, and works everywhere we've tested. First, we want add a message to our <body> before all the scripts are loaded to give ourselves and anyone else using the code some feedback.
Sending a Message
displayMessage to our inline script, and inside of the init function use the DOM
getElementByID() to assign it a value. It is a best practice to store off references to
the DOM that you plan to reuse because getting values from the DOM, indeed any form of walking the DOM, is
Wait for Touch
Now we want to change our
handleLoad function to add a click listener to our display message and
to update the message to suggest the user touch the screen. We add the click listener to the
displayMessage element and not right to the document because document click does not work on iOS
devices (iPhone, iPad, and iPod).
You may have already noticed the
handleClick function being passed with the click listener.
Unsurprisingly, we now want to create a
handleClick function. In this function we will again update
the feedback message for the user, which can be especially useful when things are not working on mobile devices
with no error console. Next we play sounds using our old friend
Sound.play. Remember back in the Basics tutorial
when we passed in ids when registering our audio? Now is when that pays off. Instead of trying to remember the
big long audio path and name string, or store it off as a global variable, we can simple pass in the
easy-to-remember ids we set. Fabulous, easy, and readable!
Ready to Rock
And that's all there is to it, you can now make sound on mobile devices. However, this only works in response to user events, so your code has to be geared towards responding to user initiated events. If that's all you need, this is the easy way to do it.
Pro-tip: It's worth noting that as long as you have a user initiated event in your immediate call stack, you can play sound. This helps lead to the next more flexible solution. This is what your code should look like at this point.
Namespace and Closure
The first change we want to make is to set up our code more like an application. If you are building something more complex, hopefully you have already taken these steps.
- create a namespace that wraps all your code
- move the business logic into an "application" object
- wrap the application object in a function closure
After our code has been migrated, we need to change the syntax to make the functions members of our application.
displayMessage variable and functions were global, declared on the window object.
Our scope has changed, because they are now part of the
MyApp object, so we want to reference them
as object properties using
this syntax. For example, instead of assigning a value to
we now assign a value to
We'll also add feedback to let users know when we are waiting for audio to load. We change
to play the loaded sounds, and provide some feedback to the user about what we are playing. Note that for this
technique to work on iOS devices, you need to initialize the Sound plugins in the
init function. We
no longer use the
handleClick function in our new
MyApp Object, so we remove it.
Next, we make a new
init function to kick off our app, which will still be called by our <body>
onload function. Our new kickoff code is going to launch the app inside of a click event.
Obviously, we will need to add a new
handleClick function, which will remove the click listener and
start our app. Removing listeners when you don't plan to use them again is a best practice, and assists with
garbage collection in your application.
Apply Application Scope
So now our application will be launch inside of a touch scope, which allows audio to play. We need to do one
more essential step: Currently, our
handleLoad function is not called in the MyApp scope. That
means it will not have access to the MyApp object (this), and that the audio is not played inside of the touch
scope. We need this function to execute in our application scope to fix these problems, which we do using the
createjs.proxy method. Createjs.proxy uses
Function.apply to set the scope that a function executes in, setting the reference of "this".
some time in research to understand it better.
Ready to Rock Everywhere
And that's all there is to it, you can now play audio on most mobile devices! If you already have an amazing application using SoundJS that you want to work on mobile devices, you can just launch it inside of a touch event and make sure sound playback is called in your application scope.
To improve this approach further, you can add browser agent sniffing to determine the browser and device you are on, and only require a touch to start when on mobile devices. Adding some style to the user feedback message would also be a nice touch. Your final code should look like the following:
This wraps up the tutorial on approaches you can use to play audio on the broadest possible range of devices and browsers. The above example has been successfully tested on Mobile Safari and Android Chrome, Firefox, Opera, and Stock Android browsers, as well as all major desktop browsers. Good places to learn more are the SoundJS online documentation and GitHub examples. A great place to get help or discuss SoundJS is the SoundJS Community page.
Hope that helps!
- Download CreateJS from the Adobe CDN.
- Get the SoundJS source code, including minified versions of SoundJS and FlashAudioPlugin from GitHub.
- Read more about SoundJS in the online docs (also available in GitHub).
- Get involved in active community discussion.