Lately, I have been experimenting with Ionic framework, because I decided that I want to code a simple game using this framework and also discover how cross-platform it is.
For those who have never heard about Ionic, I recommend you read little bit more about Ionic framework.
In short, it is a framework that allows you to write applications for Android and ios.
How it works? Well you will write a code in JavaScript and Angular JS and then with ionic framework you can transform this JavaScript app into native one, this app runs in a browser, but has the ability to talk to hardware of your phone. You can use native functionality by using ngCordova
API. For example, Camera or GPS, etc.
And because I have been experimenting with sound for my app a lot, I have found 3 ways how to play a sound.
cordovaMedia
cordovaNativeAudio
- web audio <audio>
I’d like to point out that I wrote my application mainly for Android platform so examples of code will be shown for Android.
1. cordovaMedia
Documentation: http://ngcordova.com/docs/plugins/media/.
Play-sound
PlayMedia: function (src) {
setSource(src);
var srcToPlay = getSource();
if (ionic.Platform.isAndroid()) {
var mediaRes = new Media(srcToPlay, success, error);
mediaRes.play();
return mediaRes;
}
else {
console.log("unable to play sound!");
}
},
Note
For Android, it is necessary to set file source with prefix.
Prefix is: ‘/android_asset/www/
’.
Get source function:
function getSource() {
if (ionic.Platform.isAndroid()) {
source = '/android_asset/www/' + source;
return source;
}
else {
return source;
}
}
Loop
According to the documentation, the loop works only on iOS with cordovaMedia
.
2. cordovaNativeAudio
Documentation: http://ngcordova.com/docs/plugins/nativeAudio/.
Play sound
function loadSound()
{
$cordovaNativeAudio
.preloadSimple('mySound', 'sounds/sound.mp3')
.then(function (msg) {
}, function (error) {
alert(error);
});
$scope.isSoundLoaded = true;
playNativeSound('mySound');
}
$scope.playNative = function()
{
if($scope.isSoundLoaded)
{
playNativeSound('mySound');
}
else
{
loadSound();
}
}
function playNativeSound(name){
$cordovaNativeAudio.play(name);
}
You can see the difference between cordovaNativeAudio
and cordovaMedia
very easily. With native, you have to pre-load the sound. As soon as the sound is loaded, you can play it. This is really a big difference. Thanks to this, you can play audio in a loop without any delay.
Loop
$scope.playNativeLoop = function ()
{
if($scope.isSoundLoaded)
{
$cordovaNativeAudio.loop('mySound');
}
else
{
loadSound();
$cordovaNativeAudio.loop('mySound');
}
}
3. Web Audio
This is a simple browser HTML5 audio tag. You can create it from JavaScript and play a song or using <audio>
HTML tag. I wasn’t able to play a local file on Android using Web audio. I always get the same error that file doesn’t exist with or without prefix (see the above Android prefix). No idea why :(. But you can play sound using remote URL. So you can store songs on your server and user can then play them from there.
It is also important to say here that your browser has to support HTML 5 audio. So if you decide to use this approach to play an audio, you should check compatibility on different platforms you want to support: caniuse.com-audio
Documentation:
Play Sound
$scope.playWebAudio = function()
{
try{
$scope.audio = new Audio('http://codedreaming.com/wp-content/uploads/main_tune.mp3');
$scope.audio.play();
}
catch(e){
alert(e);
}
}
Loop
$scope.playWebAudioLoop = function()
{
$scope.audio = new Audio('http://codedreaming.com/wp-content/uploads/main_tune.mp3');
$scope.audio.loop = true;
$scope.audio.play();
}
Note
Web audio supports playing a sound in a loop, but there is always a few ms delay at the end, before the song is started again. This is real trouble when your song continuously follows up, because you can hear the pause between end and start of a song.
Summary
I introduced you to 3 ways in which to play a sound using ionic framework.
cordovaMedia
– simple to use, different file paths, no loop on Android cordovaNative
– preload, support loop - web audio – your browser must support it, support loop (but delay), only remote source(?)
Hints
From my personal experience, if your code doesn’t work, it is best to run an emulator and make the app crash and then read the log and see the exception. You can also use console.log()
for logging and then see messages in emulator log. I also discovered that sometime you have to find working combination of ngcordova
API and ionic framework version in order to make the feature work.
Sources