package com.ptrprograms.androidtvmediaplayer.Activity;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.VideoView;
import com.ptrprograms.androidtvmediaplayer.Fragment.VideoDetailsFragment;
import com.ptrprograms.androidtvmediaplayer.Model.Movie;
import com.ptrprograms.androidtvmediaplayer.R;
import com.ptrprograms.androidtvmediaplayer.Util.Utils;
import java.util.Timer;
import java.util.TimerTask;
public class PlayerActivity extends Activity {
public static final String EXTRA_START_POSITION = "extra_start_position";
private final double MEDIA_BAR_TOP_MARGIN = 0.8;
private final double MEDIA_BAR_RIGHT_MARGIN = 0.2;
private final double MEDIA_BAR_BOTTOM_MARGIN = 0.0;
private final double MEDIA_BAR_LEFT_MARGIN = 0.2;
private final double MEDIA_BAR_HEIGHT = 0.1;
private final double MEDIA_BAR_WIDTH = 0.9;
private VideoView mVideoView;
private TextView mStartText;
private TextView mEndText;
private SeekBar mSeekbar;
private ImageView mPlayPause;
private ProgressBar mLoading;
private View mControllers;
private Timer mSeekbarTimer;
private Timer mControllersTimer;
private PlaybackState mPlaybackState;
private final Handler mHandler = new Handler();
private Movie mSelectedMovie;
private boolean mShouldStartPlayback;
private int mDuration;
private DisplayMetrics mMetrics;
public static enum PlaybackState {
PLAYING, PAUSED, BUFFERING, IDLE;
}
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_player );
initWindow();
initViews();
setupController();
setupControlsCallbacks();
startVideoPlayer();
mVideoView.invalidate();
}
private void initWindow() {
mMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics( mMetrics );
}
private void initViews() {
mVideoView = (VideoView) findViewById(R.id.videoView);
mStartText = (TextView) findViewById(R.id.startText);
mEndText = (TextView) findViewById(R.id.endText);
mSeekbar = (SeekBar) findViewById(R.id.seekBar);
mPlayPause = (ImageView) findViewById(R.id.playpause);
mLoading = (ProgressBar) findViewById(R.id.progressBar);
mControllers = findViewById(R.id.controllers);
mVideoView.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
if ( mControllers.getVisibility() != View.VISIBLE ) {
mControllers.setVisibility( View.VISIBLE );
}
if ( mPlaybackState == PlaybackState.PAUSED ) {
mPlaybackState = PlaybackState.PLAYING;
updatePlayButton( mPlaybackState );
mVideoView.start();
startControllersTimer();
} else {
mVideoView.pause();
mPlaybackState = PlaybackState.PAUSED;
updatePlayButton( PlaybackState.PAUSED );
stopControllersTimer();
}
}
});
}
private void setupController() {
int w = (int) (mMetrics.widthPixels * MEDIA_BAR_WIDTH);
int h = (int) (mMetrics.heightPixels * MEDIA_BAR_HEIGHT);
int marginLeft = (int) (mMetrics.widthPixels * MEDIA_BAR_LEFT_MARGIN);
int marginTop = (int) (mMetrics.heightPixels * MEDIA_BAR_TOP_MARGIN);
int marginRight = (int) (mMetrics.widthPixels * MEDIA_BAR_RIGHT_MARGIN);
int marginBottom = (int) (mMetrics.heightPixels * MEDIA_BAR_BOTTOM_MARGIN);
LayoutParams lp = new LayoutParams(w, h);
lp.setMargins(marginLeft, marginTop, marginRight, marginBottom);
mControllers.setLayoutParams(lp);
mStartText.setText(getResources().getString(R.string.init_text));
mEndText.setText(getResources().getString(R.string.init_text));
}
private void startVideoPlayer() {
Bundle bundle = getIntent().getExtras();
mSelectedMovie = (Movie) getIntent().getSerializableExtra( VideoDetailsFragment.EXTRA_MOVIE );
if( mSelectedMovie == null || TextUtils.isEmpty( mSelectedMovie.getVideoUrl() ) || bundle == null )
return;
mShouldStartPlayback = bundle.getBoolean( VideoDetailsFragment.EXTRA_SHOULD_AUTO_START, true );
int startPosition = bundle.getInt( EXTRA_START_POSITION, 0 );
mVideoView.setVideoPath( mSelectedMovie.getVideoUrl() );
if ( mShouldStartPlayback ) {
mPlaybackState = PlaybackState.PLAYING;
updatePlayButton( mPlaybackState );
if ( startPosition > 0 ) {
mVideoView.seekTo( startPosition );
}
mVideoView.start();
mPlayPause.requestFocus();
startControllersTimer();
} else {
updatePlaybackLocation();
mPlaybackState = PlaybackState.PAUSED;
updatePlayButton( mPlaybackState );
}
}
private void updatePlaybackLocation() {
if ( mPlaybackState == PlaybackState.PLAYING ||
mPlaybackState == PlaybackState.BUFFERING ) {
startControllersTimer();
} else {
stopControllersTimer();
}
}
private void play( int position ) {
startControllersTimer();
mVideoView.seekTo( position );
mVideoView.start();
restartSeekBarTimer();
}
private void stopSeekBarTimer() {
if( null != mSeekbarTimer ) {
mSeekbarTimer.cancel();
}
}
private void restartSeekBarTimer() {
stopSeekBarTimer();
mSeekbarTimer = new Timer();
mSeekbarTimer.scheduleAtFixedRate( new UpdateSeekbarTask(),
getResources().getInteger( R.integer.seekbar_delay_time ),
getResources().getInteger( R.integer.seekbar_interval_time ) );
}
private void stopControllersTimer() {
if ( mControllersTimer != null ) {
mControllersTimer.cancel();
}
}
private void startControllersTimer() {
stopControllersTimer();
mControllersTimer = new Timer();
mControllersTimer.schedule( new HideControllersTask(), getResources().getInteger( R.integer.time_to_hide_controller ) );
}
@Override
protected void onPause() {
super.onPause();
if ( mSeekbarTimer != null ) {
mSeekbarTimer.cancel();
mSeekbarTimer = null;
}
if ( mControllersTimer != null ) {
mControllersTimer.cancel();
}
mVideoView.pause();
mPlaybackState = PlaybackState.PAUSED;
updatePlayButton( mPlaybackState );
}
@Override
protected void onDestroy() {
stopControllersTimer();
stopSeekBarTimer();
super.onDestroy();
}
private class HideControllersTask extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
mControllers.setVisibility( View.GONE );
}
});
}
}
private class UpdateSeekbarTask extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
updateSeekbar( mVideoView.getCurrentPosition(), mDuration );
}
});
}
}
private class BackToDetailTask extends TimerTask {
@Override
public void run() {
mHandler.post( new Runnable() {
@Override
public void run() {
Intent intent = new Intent( getApplicationContext(), DetailsActivity.class );
intent.putExtra( VideoDetailsFragment.EXTRA_MOVIE, mSelectedMovie );
startActivity( intent );
finish();
}
});
}
}
private void setupControlsCallbacks() {
mVideoView.setOnErrorListener( new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mVideoView.stopPlayback();
mPlaybackState = PlaybackState.IDLE;
return false;
}
} );
mVideoView.setOnPreparedListener( new OnPreparedListener() {
@Override
public void onPrepared( MediaPlayer mp ) {
mDuration = mp.getDuration();
mEndText.setText( Utils.formatMillis( mDuration ) );
mSeekbar.setMax( mDuration );
restartSeekBarTimer();
}
} );
mVideoView.setOnCompletionListener( new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stopSeekBarTimer();
mPlaybackState = PlaybackState.IDLE;
updatePlayButton( PlaybackState.IDLE );
mControllersTimer = new Timer();
mControllersTimer.schedule(new BackToDetailTask(), getResources().getInteger( R.integer.time_to_hide_controller ) );
}
});
}
@Override
public boolean onKeyDown( int keyCode, KeyEvent event ) {
int currentPos = 0;
int delta = mDuration / getResources().getInteger( R.integer.scrub_segment_divisor );
if ( delta < getResources().getInteger( R.integer.min_scrub_time ) )
delta = getResources().getInteger( R.integer.min_scrub_time );
if ( mControllers.getVisibility() != View.VISIBLE ) {
mControllers.setVisibility( View.VISIBLE );
}
switch ( keyCode ) {
case KeyEvent.KEYCODE_DPAD_CENTER:
return true;
case KeyEvent.KEYCODE_DPAD_DOWN:
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
currentPos = mVideoView.getCurrentPosition();
currentPos -= delta;
if (currentPos > 0)
play(currentPos);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
currentPos = mVideoView.getCurrentPosition();
currentPos += delta;
if( currentPos < mDuration )
play( currentPos );
return true;
case KeyEvent.KEYCODE_DPAD_UP:
return true;
}
return super.onKeyDown(keyCode, event);
}
private void updateSeekbar( int position, int duration ) {
mSeekbar.setProgress( position );
mSeekbar.setMax( duration );
mStartText.setText( Utils.formatMillis( position ) );
mEndText.setText( Utils.formatMillis( duration ) );
}
private void updatePlayButton( PlaybackState state ) {
switch ( state ) {
case PLAYING:
mLoading.setVisibility( View.INVISIBLE );
mPlayPause.setVisibility( View.VISIBLE );
mPlayPause.setImageDrawable(
getResources().getDrawable( R.drawable.ic_pause_playcontrol_normal ) );
break;
case PAUSED:
case IDLE:
mLoading.setVisibility( View.INVISIBLE );
mPlayPause.setVisibility( View.VISIBLE );
mPlayPause.setImageDrawable(
getResources().getDrawable( R.drawable.ic_play_playcontrol_normal ) );
break;
case BUFFERING:
mPlayPause.setVisibility( View.INVISIBLE );
mLoading.setVisibility( View.VISIBLE );
break;
default:
break;
}
}
}