Play Music in Ionic Capacitor apps


Play Spotify like Music in Ionic 4 apps

In this post, you will learn how to play music in your Capacitor Ionic Angular app, be it for a music player or just for a notification. Capacitor is the latest buzz in hybrid app world. It is created to be a replacement and an improvement over Cordova.

In this post, you will learn

  • How to play music and sound files in Ionic 4 apps — both from local files and web urls
  • How to use music controls like next, previous, pause etc.
This demonstration is supported by Ionic 4 Spotify Starter from Enappd. Complete source code of this tutorial is available here — Ionic-4-music (capacitor branch)

If you are looking for Music functionality in Ionic 4 Angular Cordova apps, please check this blog

Let’s see a brief intro to each of the included frameworks:

  1. Ionic
  2. Capacitor

What is Ionic ?

You probably already know about Ionic, but I’m putting it here just for the sake of beginners. Ionic is a hybrid mobile app development SDK. It provides tools and services for developing hybrid mobile apps using Web technologies like CSS, HTML5, and Sass. Apps can be built with these Web technologies and then distributed through native app stores. These apps can be installed on devices by leveraging Cordova or Capacitor environment.

So, in other words — If you create Native apps in Android, you code in Java. If you create Native apps in iOS, you code in Obj-C or Swift. Both of these are powerful but complex languages. With Cordova (and Ionic) you can write a single piece of code for your app that can run on both iOS and Android (and windows!), that too with the simplicity of HTML, CSS, and JS.

It is important to note the contribution of Cordova in this. Ionic is only a UI wrapper made up of HTML, CSS and JS. So, by default, Ionic cannot run as an app in an iOS or Android device. Cordova is the build environment that containerizes (sort of) this Ionic web app and converts it into a device installable app, along with providing this app access to native APIs like Camera etc.

What is Capacitor ?

Cordova helps build Ionic web app into a device installable app. But there are some limitations of Cordova, which Capacitor tries to overcome with a new App workflow.

Capacitor is a cross-platform app runtime that makes it easy to build web apps that run natively on iOS, Android, Electron, and the web. Ionic people call these apps “Native Progressive Web Apps” and they represent the next evolution beyond Hybrid apps.

Capacitor is very similar to Cordova, but with some key differences in the app workflow

Here are the differences between Cordova and Capacitor

  1. Capacitor considers each platform project a source asset instead of a build time asset. That means, Capacitor wants you to keep the platform source code in the repository, unlike Cordova which always assumes that you will generate the platform code on build time
  2. Because of the above, Capacitor does not use config.xml or a similar custom configuration for platform settings. Instead, configuration changes are made by editing AndroidManifest.xml for Android and Info.plist for Xcode
  3. Capacitor does not “run on device” or emulate through the command line. Instead, such operations occur through the platform-specific IDE. So you cannot run an Ionic-capacitor app using a command like ionic run ios . You will have to run iOS apps using Xcode, and Android apps using Android studio
  4. Since platform code is not a source asset, you can directly change the native code using Xcode or Android Studio. This give more flexibility to developers

In essence, Capacitor is like a fresh, more flexible version of Corodva.

Plugins in Capacitor

Cordova and Ionic Native plugins can be used in Capacitor environment. In this post also, we will use Cordova-plugin-media to play music in Capacitor environment, which is wrapped by Ionic Native plugin as well.

However, there are certain Cordova plugins which are known to be incompatible with Capacitor.

Other than that, Capacitor also doesn’t support plugin installation with variables. Those changes have to be done manually in the native code.

Where is music required in apps ?

Well ! that’s a stupid question I know. Music is everywhere in today’s apps. Spotify, Youtube Music, Wynk, Gaana, etc. Other than the music streaming apps themselves, there are tonnes of other usages of music/sound in apps.

  • You definitely need sounds in a game app
  • You can play sounds when user does a specific activity in the app e.g. wins a coupon !
  • Sounds can be played for push notifications, the ones which are silently pushed in a foreground app
  • Chat messages can make a sound ! Whatsapp does that
  • …… and many more such examples

Basically music / sounds make your app more lively, more exciting. Of course you would want to avoid sounds in a professional app like LinkedIn, because people use that at work as well 😄

Structure of Post

We’ll follow a stepped approach to create a Music player app in this Ionic 4 Capacitor App. Following are the steps

  • Step 1 — Create a basic Ionic 4 Angular app
  • Step 2 — Setup Music plugin
  • Step 3 — Understand and implement Music plugin Features
  • Step 4 — Integrate Capacitor in the app
  • Step 5— Test on Android

So let’s dive right in !

Step 1 — Create a basic Ionic 4 app

I have covered this topic in detail in this blog.

In short, the steps you need to take here are

  • Make sure you have node installed in the system (V10.0.0 at the time of this blog post)
  • Install ionic cli using npm (my Ionic version is 4.6.0 )
  • Create an Ionic app using ionic start

You can create a blank starter for the sake of this tutorial. On running ionic start ionic-4-music blank , node modules will be installed. Once the installation is done, run your app on browser using

$ ionic serve

Make slight modifications to the home page as you like. My app’s home page looks like this


Home page for ionic-4-music app in Capacitor

Home page for ionic-4-music app in Capacitor

I actually borrowed the homepage UI from Enappd’s Ionic 4 Spotify starter, just to give you a glimpse of the UI and features.

Step 2 — Setup Music plugin

We are going to use an Ionic Native plugin (which is essentially wrapping a Cordova plugin) — Cordova Plugin Media. This plugin has basic music playback functionalities, along with recording capabilities. But we’ll not go into recording features for now.

Once your basic app is ready, install the plugin using following commands

$ ionic cordova plugin add cordova-plugin-media
$ npm install @ionic-native/media

With this, the plugin is installed, no extra settings. Now you have to import the plugin in app.module.ts and your homepage i.e. home.page.ts



Import music plugin in app.module.ts

Similarly import the plugin in home.page.ts and declare it in constructor as

constructor(public platform: Platform, private media: Media) {}

Step 3 — Various Music plugin Features

Now that he plugin is installed and imported correctly, we move on to integrate its methods. Let’s have a look at different methods the plugin supports

Complete source code of this tutorial is available here — Ionic-4-music (capacitor branch)

Create Media

This is the basic routine the plugin needs to perform in order to import the song/audio file into the app. There are two ways to provide music file to the plugin

  • From a local url
  • From a web url

From Local url — For demo purpose, I will use a local asset file. I have this file directly in assets folder. 


Local asset file for music playback

Local asset file for music playback

In Android devices, you need to format the music file url like this/android_asset/public/assets/file.mp3

From Web url — You can also input a web url directly. Here’s a URL for the song you can use (Please check if the URL still exists, otherwise use any other mp3 URL)

http://fabienne.sigonney.free.fr/tranquilit/Eagles - Hotel California (Acoustic).mp3

To create a playable media, you need to assign the media file to a variable via the create method of the plugin

this.curr_playing_file = this.media.create("YOUR_FILE_URL");

Now, this.curr_playing_file can be used throughout the page to play / pause/ stop the song etc.

Play / pause

The most basic function of a music player. The plugin allows you to play or pause a “created” media. The method could not have been simpler 😄

this.curr_playing_file.play();

Note — The plugin take a little time to load the media. Make sure you are not calling play() on an uncreated media variable.

Also, Paused media plays from the same place it was paused.

getDuration

This method is used to get the total length of the audio file, so you can display the time in your app (as I’ve shown in the screens above). You can get the duration by calling

this.curr_playing_file.getDuration();

But, getting duration in the plugin is a little tricky (or I would say hacky). The plugin doesn’t give away duration directly at the first call. There are two things to note

  1. If getDuration() is called right after media is created, the duration returned will be -1
  2. If getDuration() is called without playing the media file even once, the duration returned will still be -1. To avoid this, the hack we use is :
  • Create the media file as usual
  • Play the media file, but keep the volume to 0 by calling this.curr_playing_file.setVolume(0.0)
  • Call getDuration() in a loop (sadly, yes) until you find a seemingly valid value of duration for the song. Following is my code to get the duration

Get duration of the song with this Hacky method

Getting duration takes some time. Hence, as a UX feature you can keep the Play button disabled till the duration is obtained. And show a nice little loader somewhere to let the user know what is happening.

Note — Do not forget to clearInterval once the duration is obtained. Otherwise the loop will continue forever.

GetCurrentPosition

getCurrentPosition is pretty self explanatory. It tells you the current position of song, in seconds. Again, this has a hacky implementation. I hope as the plugin improves, this method would improve to have a non-hacky solution.


Get current position of song and update the variable to update the Seek Bar

Notice the toHHMMSS() function I have used for converting seconds into a mm:ss format. This is what you would like to show to your users, instead of an integer value in seconds, as shown below.



Show the time values in mm:ss format for a good UX

SeekTo

Because a great music player has the ability to jump to a particular time in the song, our plugin also has that capability. The seekTo() method allows users to jump to any moment in the song using the seekbar.

I have implemented the seek bar as an Ionic Range component, where the position of circle is controlled by the ngModel . We can update the position variable using the values from getCurrentPosition() method.

<ion-range min="0" max="{{duration}}" [(ngModel)]="position" color="light"></ion-range>

I have implemented a FastForward and a Rewind button to demonstrate this function. The associated code goes like this. E.g. Rewind button with call controlSeconds('back')


Stop

When the song is over, we need to stop it. That’s why the plugin has this method to stop the audio playback. Notice that stopping the song does not release it from the memory in Android.

this.curr_playing_file.getDuration();

Release

Releases the underlying operating system’s audio resources. This is particularly important for Android since there are a finite amount of OpenCore instances for media playback. Applications should call the release function for any Mediaresource that is no longer needed.

onStatusUpdate

This is subscribe operation. With this, we can subscribe to the status of the song — whether it is playing, paused or stopped. This is useful when we want to change the play button to pause, and vice versa.


Get status of the song to change Play / Pause icons etc.

Step 4 — Integrate Capacitor in the app

Capacitor can be attached to an existing Ionic app as well. To attach Capacitor to your existing Ionic app, run

$ ionic integrations enable capacitor

This will attach Capacitor to your Ionic app. After this, you have to init the Capacitor app with

$ npx cap init YOUR_APP_NAME YOUR_APP_ID

You should already be having YOUR_APP_NAME and YOUR_APP_ID in config.xml . Use the same here, so that there is no mismatch or confusion.

Step 5— Test on Android

Now that everything is ready, we need to build this app for Android. Why ? Because Cordova plugins do not work on browser 😆. But the good thing is … Cordova plugins work with Capacitor 😎

Before adding a platform to Capacitor, you need to build the app once. Build the app using

$ ionic build

Now add Android platform (or iOS)

$ npx cap add android

This should add Android platform to your project.


Troubleshoot Tip

If you face an error saying

Capacitor could not find the web assets directory "/Users/abhijeetrathore/ionic-4-music/www".

Check your capacitor.config.json file. Make sure the webDir field has a value of www . If not, change the webDir field to have the same value as the last parameter of the url showing up in the above error


Note, you cannot run the project directly on the phone using CLI in Capacitor. You will have to open the project in Android Studio and run using the Android Studio IDE. Open the project in Android Studio using

$ npx cap open android

Now run the app in your device using Android Studio, and you get this ! (Sample from my One Plus 6T, Android P)

Note: After adding a platform, if you make any changes in the app, you need to run ionic build and then npx cap sync to reflect those changes in the native platform


Once your app is up and running on the device, you can start testing all the functions. I have recorded a video just in case you wanna see it in action!


Play music in Capacitor Ionic app

And here you are, playing music in your own Ionic 4 Capacitor app 🎉 🎉

Conclusion

In this post, we learned how to implement music player functionalities in a Capacitor Ionic 4 app, using a Cordova plugin. We learned how to use play, pause, seek, etc functionalities. You can now implement music playback in your Ionic 4 apps and create something exciting!

This demonstration is supported by Ionic 4 Spotify Starter from Enappd. Complete source code of this tutorial is available here — Ionic-4-music (capacitor branch)

Next Steps

Now that you have learned the implementation of Music playback in Ionic Capacitor app, you can also try following blogs for Ionic apps

Ionic React

If you need a base to start your next Ionic 4 React app, you can make your next awesome app using Ionic React Full App


Ionic 4 React Full App with huge number of layouts and features

Ionic 4 React Full App with huge number of layouts and features

Ionic Angular

If you need a base to start your next Ionic 4 Angular app, you can make your next awesome app using Ionic 4 Full App


Ionic 4 Full App with huge number of layouts and features

Ionic 4 Full App with huge number of layouts and features



Title
Subtitle
Kicker