|
/* |
|
* Copyright (C) 2017 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
package com.example.exoplayer; |
|
|
|
import android.annotation.SuppressLint; |
|
import android.net.Uri; |
|
import android.os.Bundle; |
|
import android.support.v7.app.AppCompatActivity; |
|
import android.view.View; |
|
|
|
import com.google.android.exoplayer2.DefaultLoadControl; |
|
import com.google.android.exoplayer2.DefaultRenderersFactory; |
|
import com.google.android.exoplayer2.ExoPlayerFactory; |
|
import com.google.android.exoplayer2.SimpleExoPlayer; |
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; |
|
import com.google.android.exoplayer2.source.ExtractorMediaSource; |
|
import com.google.android.exoplayer2.source.MediaSource; |
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; |
|
import com.google.android.exoplayer2.ui.SimpleExoPlayerView; |
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; |
|
import com.google.android.exoplayer2.util.Util; |
|
|
|
|
|
/** |
|
* A fullscreen activity to play audio or video streams. |
|
*/ |
|
|
|
|
|
public class PlayerActivity extends AppCompatActivity { |
|
|
|
SimpleExoPlayerView playerView; |
|
SimpleExoPlayer player; |
|
private boolean playWhenReady; |
|
private int currentWindow; |
|
private long playbackPosition; |
|
|
|
@Override |
|
protected void onCreate(Bundle savedInstanceState) { |
|
super.onCreate(savedInstanceState); |
|
setContentView(R.layout.activity_player); |
|
playerView = (SimpleExoPlayerView) findViewById(R.id.video_view); |
|
} |
|
|
|
/** |
|
* {@link com.google.android.exoplayer2.RenderersFactory} sync video, audio and subtitle together |
|
* {@link com.google.android.exoplayer2.trackselection.TrackSelector} select audio, video and text from available list |
|
* {@link com.google.android.exoplayer2.LoadControl} manage video buffer |
|
*/ |
|
private void initializePlayer() { |
|
player = ExoPlayerFactory.newSimpleInstance( |
|
new DefaultRenderersFactory(this), |
|
new DefaultTrackSelector(), new DefaultLoadControl() |
|
); |
|
|
|
playerView.setPlayer(player); |
|
|
|
|
|
player.setPlayWhenReady(playWhenReady); |
|
player.seekTo(currentWindow, playbackPosition); |
|
|
|
/* |
|
* media part |
|
*/ |
|
Uri uri = Uri.parse(getString(R.string.media_url_mp4)); |
|
MediaSource mediaSource = buildMediaSource(uri); |
|
player.prepare(mediaSource, true, false); |
|
|
|
} |
|
|
|
private MediaSource buildMediaSource(Uri uri) { |
|
return new ExtractorMediaSource(uri, |
|
new DefaultHttpDataSourceFactory("ua"), |
|
new DefaultExtractorsFactory(), null, null); |
|
} |
|
|
|
@Override |
|
protected void onStart() { |
|
super.onStart(); |
|
/* |
|
Api 24 supports multiple windows, so we start it here |
|
*/ |
|
if (Util.SDK_INT > 23) { |
|
initializePlayer(); |
|
} |
|
} |
|
|
|
@Override |
|
protected void onResume() { |
|
super.onResume(); |
|
/* |
|
Before Api 24. we initialize in a later stage which is resume |
|
*/ |
|
hideSystemUi(); |
|
if ((Util.SDK_INT <= 23 || player == null)) { |
|
initializePlayer(); |
|
} |
|
} |
|
|
|
/* |
|
Prior to 24, onStop is not guarantee |
|
*/ |
|
@Override |
|
protected void onPause() { |
|
super.onPause(); |
|
if (Util.SDK_INT <= 23) { |
|
releasePlayer(); |
|
} |
|
} |
|
|
|
/* |
|
onStop is guaranteed when 24. We should delay it as much as possible. |
|
*/ |
|
@Override |
|
protected void onStop() { |
|
super.onStop(); |
|
if (Util.SDK_INT > 23) { |
|
releasePlayer(); |
|
} |
|
} |
|
|
|
/** |
|
* getCurrentPosition - keep seekbar position |
|
* getPlayWhenReady - play immediately when coming back from other app |
|
*/ |
|
private void releasePlayer() { |
|
if (player != null) { |
|
playbackPosition = player.getCurrentPosition(); |
|
currentWindow = player.getCurrentWindowIndex(); |
|
playWhenReady = player.getPlayWhenReady(); |
|
player.release(); |
|
player = null; |
|
} |
|
} |
|
|
|
/** |
|
* Make it an immersive experience on api 24 and up |
|
*/ |
|
@SuppressLint("InlinedApi") |
|
private void hideSystemUi() { |
|
playerView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE |
|
| View.SYSTEM_UI_FLAG_FULLSCREEN |
|
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); |
|
} |
|
} |