Implementing Exoplayer for Beginners in Kotlin

Nikhil Bansal
MindOrks
Published in
5 min readDec 10, 2017

Hi Developers!! This post is based on implementing Exoplayer Library to play media files on Android.

Android framework provides classes such as MediaPlayer and AudioManager to play media files. Exoplayer is an open source library by Google to play media files. This blog will guide you through process of implementing a SimpleExoPlayer to play audio files.

Which media player to use??

There are different ways to play media files on android devices. From using the default APIs provided the android framework to external libraries, there are whole lot of options. You can even create your own media player using the Codec classes included in the android framework.

  1. MediaPlayer : It is provided by the Android Framework and provides the basic implementation of the media player. It is useful to play media in a player with little/no customization options.
  2. ExoPlayer : It is an open source library maintained by Google. It provides many customization options and supports a wide range of media files including DASH and HLS streaming which is not supported by the MediaPlayer. **Important : It works on Android 4.1 and above.**
  3. Custom Player : You can build custom media player using the MediaCodec , AudioTrack and MediaDrm classes.

How does it work?

Media player contains 2 main components i.e. MediaController and MediaSession. MediaController is used to decode the media and play it. Usually both are tied with a predefined set of callbacks (play, pause, stop, etc).

Media Session

It is used to decode and play the media. It is also used for communication with the player from the app’s UI or the external clients such as Android Wear and Android Auto. You can call it the public face of your player which stores the information about the state of the player and the meta data about the media being played.

It is made up of 2 components i.e. PlaybackStateCompact and MediaMetaDataCompact . PlaybackStateCompact contains the state of the app. It can also be used to change the state of the app. The MediaMetaDataCompact class contains the metadata about the media, For Example: Name of the media, album art etc.

MediaController

It isolates the UI from the player. The UI components do not directly communicate with the player but with the controller which converts the actions to callbacks for the media session. The controller can also receive callbacks from the media session about the changes in state and accordingly update the UI. It can connect to only one media session at a time.

Where to Implement?

The main components of an music app, i.e. MediaSession and MediaController can both be defined in 2 ways :

  1. Both are defined in the Activity.
  2. MediaPlayer is defined in activity and MediaSession in service.

The implementation depends on the type of player you are building. If you are making a video player, the MediaSession and Controller should be implemented in the activity as the user leaves the activity, it is expected that the playback is stopped. In case of an audio app, it is expected that even if the user leaves the activity, the playback continues in the background so the controller can be setup in the activity whereas the session can be in a service.

This blog is based on implementing an audio app without the service component.

Lets get started!!

Step 1 : Adding the Dependencies.

Add the dependency of Exoplayer by adding the below line in your build.gradle file. Before adding the dependency, make sure to add the JCenter and Google repository.

repositories {
jcenter()
google()
}

The next step is to add the exoplayer dependency to the app module. The below dependency is used to add full library.

compile 'com.google.android.exoplayer:exoplayer:2.X.X'

Where 2.X.Xis the preferred version.

If you want to add particular feature of the exoplayer such as DASH streaming or core features, add the below lines.

compile 'com.google.android.exoplayer:exoplayer-core:2.X.X'
compile 'com.google.android.exoplayer:exoplayer-dash:2.X.X'
compile 'com.google.android.exoplayer:exoplayer-ui:2.X.X'

Step 2 : Adding view

After you have added the dependencies, the next step is to add a container view that will display the media. Exoplayer library provides SimpleExoPlayerView to display video, subtitles, album art during playback and displays playback controls using PlaybackControlView .

In your xml file, add the following line of code to add a SimpleExoPlayerView .

Step 3 : Initializing the ExoPlayer

After adding the container view, it is time to initialize the player with a media file. SimpleExoPlayer can be initialized by calling newSimpleInstance() method that takes in 2 arguments, i.e. context and a TrackSelector.

TrackSelector class is responsible for selecting the tracks that the Renderers will consume.

val trackSelector = DefaultTrackSelector()val exoPlayer = SimpleExoPlayer.newSimpleInstance(baseContext,trackSelector)exoPlayerView?.player = exoPlayer

After the exoPlayer is initialized, a MediaSession is to be created to control the playback state and store the media metadata. To create a media session, call the MediaSessionCompact constructor. The constructor expects arguments such as the context, tagName (short name for debugging purposes), componentName and a Pending Intent (for your receiver component that handle the media callbacks).

val componentName = ComponentName(baseContext, "MainActivity")val mediaSession = MediaSessionCompact(baseContext, "MainActivity",     componentName, null)

Even after the media session is created, it will not be published to the system until the setActive() method is called.

Currently, our media session is missing 1 main component i.e. PlaybackStateCompact. You can create an instance by using the PlaybackStateCompact.Builder() and calling build() method. Before calling the build method, it has to be configured to set the current capabilities of the session. After the playbackStateCompactBuilder is configured, connect it to the media session using the setPlaybackState() method.

val playbackStateCompactBuilder = PlaybackStateCompact.Builder()playbackStateCompactBuilder.setActions(
PlaybackStateCompact.ACTION_PLAY,
PlaybackStateCompact.ACTION_PAUSE,
PlaybackStateCompact.ACTION_FAST_FORWARD)
mediaSession.setPlaybackState(playbackStateCompactBuilder.build())mediaSession.isActive = true

Its almost done!! Our Exoplayer is initialized and media session has been created. Now is time to add a media file that our player will play.

Create an assets folder and add the mp3 file in it. Next, get the Uri of the file and create a MediaSource . MediaSource class is used to define and provide the media to be played by the player.

val mediaUri = Uri.parse("asset:///heart_attack.mp3")val userAgent = Util.getUserAgent(baseContext, "ExoPlayer")val mediaSource = ExtractorMediaSource(mediaUri,            
DefaultDataSourceFactory(baseContext, userAgent),
DefaultExtractorsFactory(), null, null)
exoplayer?.prepare(mediaSource)

That’s it! You can find this project on Github here

This post completes the implementation of the Exoplayer for local file.. Hope it helps you to be comfortable with setting up an database for your app

If you liked it, show some love 👏🏻and share more! Keep practicing and happy coding!

--

--