aLL aBOUT eXOPLAYER

Alok Verma
MindOrks
Published in
3 min readNov 27, 2018

Hello Guys, Hope you all are doing very well.

Today we are going to talk about Exoplayer library and about its implementation. Very popular apps like youtube, Udemy, Google photos and much more use exoplayer for playing their video/audio related content. In this blog, we will also talk about some common feature like play/pause fast forward, rewind some controllers that exoplayer provides by default.

So first of all, what is the need of exoplayer, We already have Android default Media player class then why we need exoplayer. The media player is not much customizable, we can add more feature than basic play pause events, Also its totally depends on device os version too, some of the Android OS supports some media formats and others don't support same media format. We can not debug much deeper in media player as its very simple to use and we don't have to provide anything just basic playback URL and start the media player. So we can say its very easy to use but if we have requirements to customize playback speed, supports lots of formats then we should use Exoplayer.

How to use exoplayer-

Add Gradle dependency for exoplayer -

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

Or you can add different dependency depending on your requirements.

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

The available library modules are listed below. Adding a dependency to the full library is equivalent to adding dependencies on all of the library modules individually.

  • exoplayer-core: Core functionality (required).
  • exoplayer-dash: Support for DASH content.
  • exoplayer-hls: Support for HLS content.
  • exoplayer-smoothstreaming: Support for SmoothStreaming content.
  • exoplayer-ui: UI components and resources for use with ExoPlayer.

Now come to the coding part, In starting we need to write more code for exoplayer than a media player. Here is code snippet for creating exoplayer instance-

private SimpleExoPlayer createFullPlayer() {
TrackSelection.Factory videoTrackSelectionFactory
= new AdaptiveTrackSelection.Factory(new DefaultBandwidthMeter());
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectorParameters = new DefaultTrackSelector.ParametersBuilder().build();
trackSelector.setParameters(trackSelectorParameters);
LoadControl loadControl = new DefaultLoadControl();
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(playerView.getContext()),
trackSelector, loadControl);
player.setPlayWhenReady(true);
player.prepare(mediaSourceBuilder.getMediaSource(false));
return player;
}

We have to create an exoplayer instance -

SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(playerView.getContext()),
trackSelector, loadControl);

As you can see in above code, we have to pass media source to this player in prepare method-

player.prepare(mediaSourceBuilder.getMediaSource(false));

For fetching media source we are using a mediaSourceBuilder class that will get you MediaSource.

public class ExoPlayerMediaSourceBuilder {

private DefaultBandwidthMeter bandwidthMeter;
private Context context;
private Uri uri;
private int streamType;
private Handler mainHandler = new Handler();

public ExoPlayerMediaSourceBuilder(Context context) {
this.context = context;
this.bandwidthMeter = new DefaultBandwidthMeter();
}

public void setUri(Uri uri) {
this.uri = uri;
this.streamType = Util.inferContentType(uri.getLastPathSegment());
}

public MediaSource getMediaSource(boolean preview) {
switch (streamType) {
case C.TYPE_SS:
return new SsMediaSource(uri, new DefaultDataSourceFactory(context, null,
getHttpDataSourceFactory(preview)),
new DefaultSsChunkSource.Factory(getDataSourceFactory(preview)),
mainHandler, null);
case C.TYPE_DASH:
return new DashMediaSource(uri,
new DefaultDataSourceFactory(context, null,
getHttpDataSourceFactory(preview)),
new DefaultDashChunkSource.Factory(getDataSourceFactory(preview)),
mainHandler, null);
case C.TYPE_HLS:
return new HlsMediaSource(uri, getDataSourceFactory(preview), mainHandler, null);
case C.TYPE_OTHER:
return new ExtractorMediaSource(uri, getDataSourceFactory(preview),
new DefaultExtractorsFactory(), mainHandler, null);
default: {
throw new IllegalStateException("Unsupported type: " + streamType);
}
}
}

private DataSource.Factory getDataSourceFactory(boolean preview) {
return new DefaultDataSourceFactory(context, preview ? null : bandwidthMeter,
getHttpDataSourceFactory(preview));
}

private DataSource.Factory getHttpDataSourceFactory(boolean preview) {
return new DefaultHttpDataSourceFactory(Util.getUserAgent(context,
"com.exo.demo"), preview ? null : bandwidthMeter);
}

This is the basic exoplayer instance creation and passes media source depending on stream type to the exoplayer instance, once we have created exoplayer instance we have to attach this instance to player view-

playerView.setPlayer(player);

A player view is a part of exoplayer UI lib part.

<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="player_view" />

If we want to customize controller of player view then we have to pass layout to player view -

app:controller_layout_id="@layout/exo_progress"

In this example, we are just using play pause button of exoplayer in the centre of the player.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageButton android:id="@id/exo_play"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#CC000000"
style="@style/ExoMediaButton.Play"/>

<ImageButton android:id="@id/exo_pause"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#CC000000"
style="@style/ExoMediaButton.Pause"/>

</FrameLayout>

In this article, we have discussed three thing —

First, create an exoplayer instance

pass the media source in this instance

create a custom controller layout.

Thanks,

Alok V.

--

--

Alok Verma
MindOrks

Sr. Software Engineer @OYO, Cinema fanatic, Technology enthusiast.