DEV Community

Abdurahman Adilovic
Abdurahman Adilovic

Posted on

3 2

Building a podcast app series: 3. Exoplayer

What is a podcast app if not a wrapper around a media player? And, if we talk Android, there is the only one media player worth considering, ExoPlayer, made by Google engineers. Let’s look at how can we connect all the pieces we have built so far and actually connect the ExoPlayer with the view within the app.

ExoPlayer

Exoplayer is very powerful and modular, we are going to use just a fraction of what ExoPlayer really offers. ExoPlayer has a couple of core components that have to work together for it to play anything, in no particular order:

  1. ExoPlayer instance
  2. MediaSource

We need to create an ExoPlayer instance and hold it in memory since it is pretty expensive to create. We will reuse a single instance throughout the app. For it to play anything, we need to create a MediaSource. These sources are basically different types of streams that ExoPlayer has to read in order to fetch the audio data and play it. There are other important parts to the ExoPlayer ecosystem but for starters, we need those two basic things.

ExoPlayer instance

This is the heart of ExoPlayer and the object itself. We can simply create a single instance and pass or not pass a bunch of configuration options. Let’s keep it simple and create a basic instance:

val player = SimpleExoPlayer.Builder(context).build()
Enter fullscreen mode Exit fullscreen mode

MediaSource

So the name of this class is pretty self-explanatory, we have to be aware of the fact that there are a couple of different media sources, depending on the actual source that serves the content:

  • DashMediaSource for DASH.
  • SsMediaSource for SmoothStreaming.
  • HlsMediaSource for HLS.
  • ProgressiveMediaSource for regular media files.

Let’s create a simple media source:

val mediaSource =
   ProgressiveMediaSource.Factory(dataSourceFactory).
        createMediaSource(Uri.parse(it.mp3Url))        
  exoPlayer.prepare(mediaSources)

Enter fullscreen mode Exit fullscreen mode

And that’s it. We can now play an episode!

Since we are building a podcast player, it is safe to assume we will never play one episode at a time, so we need a way to tell ExoPlayer to play the next item when one item is finished playing. To handle that, ExoPlayer has a concept of the concatenated media source. We can bundle together a bunch of media sources, they don’t have to be of the same type, and attach that source to the ExoPlayer instance.

val mediaSources = (listOf(currentEpisode) + _playlist).map {
   ProgressiveMediaSource.Factory(dataSourceFactory).
        createMediaSource(Uri.parse(it.mp3Url))        
   }.toTypedArray()
exoPlayer.prepare(ConcatenatingMediaSource(*mediaSources)
Enter fullscreen mode Exit fullscreen mode

So instead of passing just one media source, we can pass in a concatenating media source and the ExoPlayer will automatically play all episodes from that playlist.

Browse the full code on this link and in the next article, we will talk about a foreground service that needs to run our ExoPlayer and keep our app in the background so Android does not shut down our app to claim more resources :).

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay