How to deal with ExoPlayer. Part-2📹

Ali Azaz Alam
AndroidPub
Published in
3 min readApr 4, 2019

Simple steps by which we can easily achieve the player view in the name of EXOPLAYER…

Hi!! In this lesson we will work on basics structuring of app and some cool features of ExoPlayer. If you cannot read lesson-1 How to deal with ExoPlayer Part-1 then please read out. All the variables use in this lesson is referring from previous lesson.

Let’s start……

Current Video Index

// Get current playing video index
exoPlayerInstance.getCurrentWindowIndex()

Listener

You can set listener from below available code that call in the scenario when one video is going to end and next video getting ready to play. Listener can create through ExoPlayer instance — Here is the snippet 💥

exoPlayerInstance.addListener(new Player.EventListener() {@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
//Code here
}

@Override
public void onPlayerError(ExoPlaybackException error) {
exoPlayerInstance.retry();
}
});

360 Degree video

One more news 👏 ExoPlayer also supports 360 degree video. But there is some limitation for playing these videos that we can’t switch from normal playing video view to 360 view.

XML Attribute ‘Surface_Type’ for 360 degree video:

<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player_view"
…………………
app:surface_type="spherical_view"
/>

Structuring App

Let’s move forward for structuring the app

Do some tweaks, like show video name of currently playing video in TextView and build functionality that’s the video don’t play if the app goes in background and regain its timeline when user route back to app. For this we’ve to deal with onStart, onPause and onStop events. We also have to initialize two variables playbackPosition [hold the current position of video] and currentWindow [hold the last playing video index].

Long playbackPosition = new Long(0);
int currentWindow = 0;

Firstly, we’re going to define some functions that will utilize in lifecycle events

private void restartPlayer() {
playerView.setPlayer(exoPlayerInstance);
exoPlayerInstance.seekTo(currentWindow, playbackPosition);
}
private void stopPlayer() {
if (exoPlayerInstance != null) {
playbackPosition = exoPlayerInstance.getCurrentPosition();
currentWindow = exoPlayerInstance.getCurrentWindowIndex();
//it’ll stop playing the video
exoPlayerInstance.setPlayWhenReady(false);
playerView.onResume();
}
}

Now, routing to work with events:

@Override
protected void onStart() {
super.onStart();
if (exoPlayerInstance != null) {
restartPlayer();
}
}
@Override
public void onPause() {
super.onPause();
if (Util.SDK_INT <= 23) {
stopPlayer();
}
}
@Override
public void onStop() {
super.onStop();
if (Util.SDK_INT > 23) {
stopPlayer();
}
}

Compile all snippets with some additions

The whole activity code snippet can becomes ➡

public class VideoPlayingActivity extends AppCompatActivity {TextView txtName;
PlayerView playerView;
SimpleExoPlayer exoPlayerInstance;
String Directory;
DataSource.Factory dataSourceFactory;
Long playbackPosition = new Long(0);
int currentWindow = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_playing);
settingComponents();
setupExoPlayer();
settingListener();
}
private void settingComponents() {playerView = findViewById(R.id.player_view);
txtName = findViewById(R.id.txtName);
//Setup Directory
Directory = Environment.getExternalStorageDirectory() + File.separator + "EXOPLAYER-SAMPLE";
// Produces DataSource instances through which media data is loaded.
dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "simpleExoPlayer"));
}
private void setupExoPlayer() {
//Setup Exoplayer
exoPlayerInstance = ExoPlayerFactory.newSimpleInstance(this);
// This is the MediaSource representing the media to be played.// Getting media from raw resource
MediaSource firstSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.landscape));
// Getting media from sdcard storage
MediaSource secondSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(Directory + File.separator + "landscape2"));
ConcatenatingMediaSource concatenatedSource = new ConcatenatingMediaSource(firstSource, secondSource);// Prepare the exoPlayerInstance with the source.
exoPlayerInstance.prepare(concatenatedSource);
}private void settingListener() {exoPlayerInstance.addListener(new Player.EventListener() {
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// Set video name in textview
txtName.setText("Playing: " + getVideoName()[exoPlayerInstance.getCurrentWindowIndex()].toUpperCase());
}
@Override
public void onPlayerError(ExoPlaybackException error) {
exoPlayerInstance.retry();
}
});
}private String[] getVideoName() {
return new String[]{"landscape2", "landscape"};
}
private void stopPlayer() {
if (exoPlayerInstance != null) {
playbackPosition = exoPlayerInstance.getCurrentPosition();
currentWindow = exoPlayerInstance.getCurrentWindowIndex();
exoPlayerInstance.setPlayWhenReady(false);
playerView.onResume();
}
}
private void restartPlayer() {
playerView.setPlayer(exoPlayerInstance);
exoPlayerInstance.seekTo(currentWindow, playbackPosition);
}
@Override
protected void onStart() {
super.onStart();
if (exoPlayerInstance != null) {
restartPlayer();
}
}
@Override
public void onPause() {
super.onPause();
if (Util.SDK_INT <= 23) {
stopPlayer();
}
}
@Override
public void onStop() {
super.onStop();
if (Util.SDK_INT > 23) {
stopPlayer();
}
}
}

Waooo 😎 our ExoPlayer implementation is done. Let’s run the app on device 📱

Thanks for spending your precious time in reading this article. If you liked it then Claps 👏 multiple times to say Thanks and helps others by referring it.

--

--

Ali Azaz Alam
AndroidPub

@AndroidAppsDeveloper, @OpensourceContributor, @Writer @Researcher