package com.kickstarter.ui.activities;
import android.annotation.TargetApi;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.SurfaceView;
import android.view.View;
import android.widget.MediaController;
import android.widget.ProgressBar;
import com.google.android.exoplayer.AspectRatioFrameLayout;
import com.google.android.exoplayer.ExoPlayer;
import com.jakewharton.rxbinding.view.RxView;
import com.kickstarter.R;
import com.kickstarter.libs.ApiCapabilities;
import com.kickstarter.libs.BaseActivity;
import com.kickstarter.libs.KSRendererBuilder;
import com.kickstarter.libs.KSVideoPlayer;
import com.kickstarter.libs.qualifiers.RequiresActivityViewModel;
import com.kickstarter.libs.rx.transformers.Transformers;
import com.kickstarter.viewmodels.VideoViewModel;
import com.trello.rxlifecycle.ActivityEvent;
import butterknife.Bind;
import butterknife.ButterKnife;
import rx.android.schedulers.AndroidSchedulers;
@RequiresActivityViewModel(VideoViewModel.ViewModel.class)
public final class VideoActivity extends BaseActivity<VideoViewModel.ViewModel> implements KSVideoPlayer.Listener {
private MediaController mediaController;
private KSVideoPlayer player;
private long playerPosition;
protected @Bind(R.id.video_player_layout) View rootView;
protected @Bind(R.id.surface_view) SurfaceView surfaceView;
protected @Bind(R.id.loading_indicator) ProgressBar loadingIndicatorProgressBar;
protected @Bind(R.id.video_frame) AspectRatioFrameLayout videoFrame;
@Override
public void onCreate(final @Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_player_layout);
ButterKnife.bind(this);
viewModel.outputs.preparePlayerWithUrl()
.compose(Transformers.takeWhen(lifecycle().filter(ActivityEvent.RESUME::equals)))
.compose(bindToLifecycle())
.subscribe(this::preparePlayer);
mediaController = new MediaController(this);
mediaController.setAnchorView(rootView);
RxView.clicks(rootView)
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(__ -> toggleControlsVisibility());
}
@Override
public void onDestroy() {
super.onDestroy();
releasePlayer();
}
@Override
public void onPause() {
super.onPause();
releasePlayer();
}
@Override
public void onStateChanged(final boolean playWhenReady, final int playbackState) {
if (playbackState == ExoPlayer.STATE_ENDED) {
finish();
}
if (playbackState == ExoPlayer.STATE_BUFFERING) {
loadingIndicatorProgressBar.setVisibility(View.VISIBLE);
} else {
loadingIndicatorProgressBar.setVisibility(View.GONE);
}
}
@Override
public void onWindowFocusChanged(final boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
rootView.setSystemUiVisibility(systemUIFlags());
}
}
@TargetApi(19)
private int systemUIFlags() {
final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN;
return ApiCapabilities.canSetImmersiveSystemUI()
? flags | View.SYSTEM_UI_FLAG_IMMERSIVE
: flags;
}
private void releasePlayer() {
if (player != null) {
playerPosition = player.getCurrentPosition();
player.release();
player = null;
}
}
public void preparePlayer(final @NonNull String videoUrl) {
// Create player
player = new KSVideoPlayer(new KSRendererBuilder(this, videoUrl));
player.setListener(this);
player.seekTo(playerPosition); // todo: will be used for inline video playing
// Set media controller
mediaController.setMediaPlayer(player.getPlayerControl());
mediaController.setEnabled(true);
player.prepare();
player.setSurface(surfaceView.getHolder().getSurface());
player.setPlayWhenReady(true);
}
public void toggleControlsVisibility() {
if (mediaController.isShowing()) {
mediaController.hide();
} else {
if (isMediaControllerAttachedToWindow()) {
// Attempt fix for crash reports from Remix Mini / 5.1 where the media controller is attached to a window
// but not showing. Adding it again crashes the app, so return to avoid that.
return;
}
mediaController.show();
}
}
@TargetApi(19)
private boolean isMediaControllerAttachedToWindow() {
return ApiCapabilities.canCheckMediaControllerIsAttachedToWindow() && mediaController.isAttachedToWindow();
}
}