Audio in the background for Ionic / Capacitor app

Hello all,

Previously I’ve used “@ionic-native/media” to play audio, but re-architecting my app, I tried using HTML5 audio (combined with MediaSession), and it seems to have come a long way.

My main problem seems to be that iOS shuts down my app after X minutes (sometimes a short time sometimes a longer time) when playing the audio in the background.

I’ve looked at various plugins like “cordova-plugin-background-mode” etc., but people typically write “Doesn’t work anymore” and there’s a lot of conflicting information out there. Is there a Capacitor 5 compatible preferred way to make this work with HTML5, or will I have to go back to a native audio plugin?

2 Likes

Hi, did you find any answers to this?

Yup, I had the same issues with HTML5. It works great until the app goes into the background. I also needed to support audio and background music playing with the option to control the volume of the background music which you cannot do via HTML5 on iOS.

I tried several different existing Cordova and Capacitor plugins and nothing worked for me. So, I ended up creating my own plugin.

It’s opensource? I don’t think it is, but asking just in case :slight_smile:

It’s not as it is considered a “local plugin” integrated directly into my app (reference).

I wouldn’t mind sharing my code though. It is somewhat specific to my use case and has a few quirks/updates that are on my list to fix/do. But, it might at least give you a good starting point. It is also specifically designed around playing audio from HTTPS/URLs, not local audio.

Have you looked at GitHub - capacitor-community/native-audio? I think it has it’s own problems though. One being it only plays local audio files.

Thats my issue - I need do play mp3 hosted on a webserver and m3u8 (hls audio). It’s kinda of a legacy app, so for now I will continue to use cordova-plugin-media , but I’m still searching for a better option.

Out of curiosity, what issues are you running into with that Cordova plugin?

With cordova-plugin-media itself, no issue.

But I want to show the music controls - the notification with music title, cover picuture, buttons to play and pause… and there lies the troubles - most of the plugins that does that are severely outdated.

After some search, I found capacitor-media-session that works fine on android and uses the MediaSession api on ios, but it will only work on ios if it’s a real html5 audio playing (it’s a limitation of MediaSession itself), so it doesn’t show anything because I’m not really using the audio tag.

Got ya. Yeah, I searched far and wide and didn’t find anything that fit my needs; hence, why I created my own.

On iOS, I’m using MediaPlayer.MPNowPlayingInfoCenter and MediaPlayer.MPRemoteCommandCenter for the lock screen controls. For playing the audio, AVFoundation.

On Android, I am using Google’s ExoPlayer, now AndroidX Media which handles the lock screen controls and such. The most complicated part was figuring out how to incorporate it into a service for background play.

1 Like

Hey @twestrick,

I wouldn’t mind sharing my code though. It is somewhat specific to my use case and has a few quirks/updates that are on my list to fix/do. But, it might at least give you a good starting point. It is also specifically designed around playing audio from HTTPS/URLs, not local audio.

That is exactly what I need. So if you’re still willing to share your code, that would be a much appreciated and huge help.

Yeah, I can put some code snippets together.

1 Like

Ok, here is a sample repo! Hopefully it gives you a good starting point. Creating the Android service was probably the most confusing thing :sweat_smile: The media player on iOS was also a hassle. It seemed buggy when testing. Hence, some interesting logic…lol. We are using this code in production. I’ve listed a few known issues that I am aware of but haven’t had a chance to fix.

Let me know if you have any questions.

2 Likes

Thanks @twestrick! I mantain a radio app and I’m still using cordova-plugin-media, and was in search for a better option, but hadn’t found anything that was a significant improvement. I will try your code latter, but I’m quite certain that it will fit my needs perfectly!

1 Like

Hi @twestrick ! Got it working on android! Just needed to add

implementation 'com.google.android.exoplayer:exoplayer-hls:2.18.1'

to my android/app/build.gradle because I need to play hls streams.

I just need a bit more of imformation on how to handle the ios/swift side of the things :eyes:

1 Like

Any specific questions for iOS? I don’t recall what I did but I looked at the MR/PR where it was implemented when creating the example repo to see what all changed.

I am pretty sure you just create the files in XCode and turn on the Audio Background permission. Surprisingly, the iOS side was actually easier! :grin:

There are some additional steps to create the notification icon on Android and media player icons on iOS but I didn’t document that since it is somewhat specific to your use case and I don’t recall how to do it…lol. Pretty sure XCode at least has a GUI for it.

oh, got it working on ios too :slight_smile:

Now I need to adjust things according to what my app needs, fix some old bugs and remove maybe all the still remaining cordova libs. Thanks again @twestrick! I was using thd old cordova-plugin-media, and while it worked, it’s not a robust solution. It’s an radio app, and when changing radio there was some random timeouts (trouble with http requests, etc). Handling this part with exoplayer made this station selection immediately more stable.

1 Like

A minor bug maybe: setting useForNotification to false keeps the player from working at all.

Hmmm…you should always have one of the active tracks set to true for useForNotification. If you have one track playing, it should be set to true. If you have two playing, let’s say one being voice and one being background music, the voice track should be set to true.