September 24th, 2018

Playing MP3s and other audio in Ionic 3


Ah, playing a simple audio file in an Ionic 3 project. What I thought would take minutes took hours of trial and error. Let this tutorial be an oasis. Or at the very least, a reminder for me next time I need to do this seemingly simple action.

We’ll be using the following:

  • Ionic 3
    • Version 3.20.0, but other 3.x.x versions should be fine.
  • Ionic Native Audio plugin
  • An MP3 file of your choice.

Prerequisites

This tutorial assumes you have already setup an Ionic 3 project. There's great documentation on this here.

I'll also be showing you how to play audio on a user generated page, as opposed to the default home page. The process is the same for both, with the user generated page requiring a few extra little tweaks.

Heads Up!

Native Audio plugin requires Cordova, so audio will only work while running on a real device. It will not work in the browser.

You can run on a device by plugging it in via USB and running ionic cordova run ios --livereload.

If you run into a build error, try this article for a possible solution.

First things first, install the Native Audio plugin into your project following the directions here. It should be something like this:

Terminal
ionic cordova plugin add cordova-plugin-nativeaudio
npm install --save @ionic-native/native-audio@4

Next, we need to add Native Audio to our app.module.ts file, located in src/app/app.module.ts.

src/app/app.module.ts
// Import the plugin at the top (along with other imports)
import { NativeAudio } from '@ionic-native/native-audio';

@NgModule({
  // ...
  providers: [
    // ...
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    NativeAudio, // Add NativeAudio to providers
  ]
})

A great explanation for Ionic Providers can be found here if you'd like to learn more.

Next, let’s make a new page using the Ionic CLI. You’re welcome to rename AudioTest to whatever you’d like.

Terminal
ionic generate page AudioTest

This will create a new page at src/pages/audio-test. Open audio-test.ts so we can add the required parts.

Native Audio can only run once the platform is ready. To do that, we’ll need to run the required code within a specific platform ready function. At the top of audio-test.ts, add or edit to the following:

src/pages/audio-test/audio-test.ts
// The important addition is 'Platform'
import { IonicPage, NavController, NavParams, Platform } from 'ionic-angular';
// ...
// Add this import after the rest
import { NativeAudio } from '@ionic-native/native-audio';

Then, in the constructor:

src/pages/audio-test/audio-test.ts
// The two important additions are Platform and NativeAudio at the end
constructor(
    public navCtrl: NavController, 
    public navParams: NavParams, 
    public platform: Platform, 
    private nativeAudio: NativeAudio) {

      // The Native Audio plugin can only be called once the platform is ready
      this.platform.ready().then(() => { 
          console.log("platform ready");

          // This is used to unload the track. It's useful if you're experimenting with track locations
          this.nativeAudio.unload('trackID').then(function() {
              console.log("unloaded audio!");
          }, function(err) {
              console.log("couldn't unload audio... " + err);
          });

          // 'trackID' can be anything
          this.nativeAudio.preloadComplex('trackID', 'assets/audio/test.mp3', 1, 1, 0).then(function() {
              console.log("audio loaded!");
          }, function(err) {
              console.log("audio failed: " + err);
          });
      });
  }

A quick explanation of this.nativeAudio.preloadComplex('trackID', 'assets/audio/test.mp3', 1, 1, 0) and what it’s doing:

  • 'trackID' is a unique ID used for playing and stopping audio.
  • 'assets/audio/test.mp3' is the path to the track.
  • 1 is the volume (from 0.1 to 1.0)
  • 1 is the number of multichannel voices available.
    • Not 100% what this is for, but 1 seems to work just fine for most tracks.
  • 0 is the delay to starting.

Finally, just create a new function and call it to begin playing audio!

src/pages/audio-test/audio-test.ts
playAudio() {
      console.log("playing audio");

      this.nativeAudio.play('trackID').then(function() {
          console.log("playing audio!");
      }, function(err) {
          console.log("error playing audio: " + err);
      });
}

Pro Tip

You can see the output on your device by opening Safari and select your phone from the Develop menu bar option (assuming you use macOS).