Building a Global Audio Player in React Native 🎧

Dhruv
Dhruv
Jan 21 · 6 min read
A whirlwind tour of the global audio player in our Finimize app
A whirlwind tour of the global audio player in our Finimize app
A whirlwind tour of the global audio player in our app.

Here at Finimize we’ve been working hard to bring you amazing audio to listen to in the app. In this post, we’re going to dive a bit into how we built our audio player, and how you can do the same thing in react-native.

Specifically, in order to create a fully-functional, global audio player, we harnessed the following features from a react-native audio library:

  • Streaming audio
  • Playing audio files over the network
  • Adding support for playing audio in the background
  • Seeking, skipping, adjusting rates, and jumping around

We also implemented specific features on top of the features provided by the library, including:

  • An easy, globally accessible interface to create playlists inside our app
  • Strong typing to help make sure that we’re passing in the correct object structure

We don’t cover it in this post, but with the features we build here, we can extend to persist the playlist state through app sessions, and even add offline audio support.

We’ll explore the engineering choices we made while implementing the audio functionality, as well as the code required to get you up and running with playing audio files, whether that’s music, podcasts, or your own personal radio show.

Throughout this post, our snippets will be in Typescript — if you’re not used to Typescript syntax, don’t fret! We’ll be here to walk you through the code.

See the different functionality that’s possible, including seeking and rate adjustment.

The first step is to explore possible library options. When we implemented this, the current options we had were:


Taken from https://medium.com/@emmettharper/the-state-of-audio-libraries-in-react-native-7e542f57b3b4

Using the above diagram, we know that Finimize falls in the upper-right quadrant, as we wanted to ability to stream audio files (as they can be often quite large), over the network (so we don’t have to download all the files first). Neither react-native-sound or react-native-audio-toolkit support streaming audio. react-native-track-player supports background audio on iOS and Android, streaming audio, custom audio controls, as well as supporting passing in audio urls. For these reasons, we decided to use react-native-track-player. This allowed us to work towards building a cross-platform audio player.

A good breakdown of the various audio player libraries, and their strengths can be found here: https://medium.com/@emmettharper/the-state-of-audio-libraries-in-react-native-7e542f57b3b4 (Oct 2018).

As stated above, on top of the basic functionality provided by the player, we needed some extra functionality such as adding to playlists. We also wanted to store the playlist in memory, so we could use it offline, and persist the audio state through app uses. So we decided to wrap the library with a playlist controller that keeps us in full control of what’s going on. Let’s get started — full-steam ahead! 🚂


Using the example from the documentation (https://react-native-kit.github.io/react-native-track-player/)

First things first — we need to add, and set up the library. The documentation has a great page here (https://react-native-kit.github.io/react-native-track-player/install/) which can help you to get started.

Next, we wanted to set up the audio player. We decided to wrap the functionality of the library, so we can be in full control of the state of the player at any given time. Let’s create a file.

Here we start to create the wrapper around the react-native-track-player library

This now gives us easy access to the player, and we can set it up in our App component, either using ComponentDidMount, or UseEffect, depending on whether you’re using a functional or class component. We then need to register the playback service with our app — usually in our main index file, and initialise our track player component.

We instantiate our track player, so we can use it across the app

Again, the library has a good guide for getting started with using the player, found here: https://react-native-kit.github.io/react-native-track-player/api/

We’re now ready to use our player! Let’s flesh it out so we can add some more features. We now want to add the ability to add tracks to the track player, so let’s add the below function to the file.

We create a track, with the necessary parameters

We can now add tracks to the Track Player! We’d want to be able to do basic things to those tracks, so let’s add some basic utility helper functions to wrap expected functionality from the library: play / pause, next, and previous.

We write our base functions for the library: play / pause, next and previous

Great. We can now start working on our Playlist API, which will allow us to manage adding multiple items to the track player, and move through them. In general, we want our Playlist API to be our main point of contact with the track player — so we again wrap some of the functionality we made in the Track Player, so we don’t have to interact with it directly.

Below, we use unstated (https://github.com/jamiebuilds/unstated) to manage the state of our Playlist Controller. This allows us to access this playlist across our app, so we can access the currently playing item and the playlist everywhere. We chose to use unstated, but you could just as easily use any state management solution, such as redux, to store this information.

We create our playlist controller, that allows us to add more complex playlist-ing functionality

We can access our state globally by subscribing to it. For getting started with unstated, there’s some great examples on the repo homepage, linked above.

How we can subscribe to our playlist controller state throughout our app

This state works offline, so when we subscribe to it, we won’t need to do any additional data fetching (other than the file itself). By persisting this state to async storage, we could even persist the state throughout app sessions.

We’ve now initialised the playlist controller, and we’ve wrapped the functionality we declared in the track player — play, pause etc. We also now want to add the actual playlist functionality, so we can add to the queue, keep track of the currently playing item and more. We first need to add a couple of more functions to our track player to manage the playlist additions.

Manage adding tracks to a queue, using our new, shiny playlist controller

After this, we can add the playlist management functions to our playlist controller.

We add our playlist management functions to the controller

We’re nearly there! We now have a way to maintain a playlist state, and skip between items in the playlist. Finally, we need to add a listener, so we can update the currently playing item on the track change. react-native-track-player provides us with a track-change listener that we can use. We need to add the ability to add the listeners to our Track Player first.

We add the track change listeners, that allows us to keep our playlist controller in sync with the current playing track

And now we can add the track-change listener to the playlist controller

And make sure to be able to remove that listener when we’re done with it

We’re done! All that’s now required from us is to add items to the playlist, using our createPlaylistFrom function.

Some (terribly named) example tracks for our fancy new global media player.

As you can see, using this format, we can manage the tracks in our playlist. You can now see how by using this controller, it’d be easy for a component to add to, or modify the playlist queue.


In this post we’ve shown you a rough outline about how you could manage a playlist state in react native — we’re well on the way to building a global audio player. However, we’d want a nice UI to manage all the functionality we’ve created in our controllers. In the next post, we’ll show you how to create a media player UI to show artwork, play / pause, skip through tracks, and present what’s playing to a user in a nice way.

Thanks for reading!

👏 (If you found this helpful, and would like to hear more, please feel free to give me some )


⚡️ New to Finimize? We’re on a mission to empower millennials to become their own financial advisors.

📱 Find out more by subscribing to our financial email newsletter or downloading our app. By the way, we’re hiring!

💵 You can also get £20 off our premium subscription with this link!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade