/*
* Copyright 2014 Mario Guggenberger <mg@protyposis.net>
*
* 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 net.protyposis.android.mediaplayerdemo;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.Toast;
import net.protyposis.android.mediaplayer.MediaPlayer;
import net.protyposis.android.mediaplayer.MediaSource;
import net.protyposis.android.mediaplayer.VideoView;
public class VideoViewActivity extends Activity {
private static final String TAG = VideoViewActivity.class.getSimpleName();
private VideoView mVideoView;
private ProgressBar mProgress;
private MediaController.MediaPlayerControl mMediaPlayerControl;
private MediaController mMediaController;
private Uri mVideoUri;
private int mVideoPosition;
private float mVideoPlaybackSpeed;
private boolean mVideoPlaying;
private MediaSource mMediaSource;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videoview);
Utils.setActionBarSubtitleEllipsizeMiddle(this);
mVideoView = (VideoView) findViewById(R.id.vv);
mProgress = (ProgressBar) findViewById(R.id.progress);
mMediaPlayerControl = mVideoView; //new MediaPlayerDummyControl();
mMediaController = new MediaController(this);
mMediaController.setAnchorView(findViewById(R.id.container));
mMediaController.setMediaPlayer(mMediaPlayerControl);
mMediaController.setEnabled(false);
mProgress.setVisibility(View.VISIBLE);
// Init video playback state (will eventually be overwritten by saved instance state)
mVideoUri = getIntent().getData();
mVideoPosition = 0;
mVideoPlaybackSpeed = 1;
mVideoPlaying = false;
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mVideoUri = savedInstanceState.getParcelable("uri");
mVideoPosition = savedInstanceState.getInt("position");
mVideoPlaybackSpeed = savedInstanceState.getFloat("playbackSpeed");
mVideoPlaying = savedInstanceState.getBoolean("playing");
}
@Override
protected void onResume() {
super.onResume();
if(!mVideoView.isPlaying()) {
initPlayer();
}
}
private void initPlayer() {
getActionBar().setSubtitle(mVideoUri+"");
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer vp) {
mProgress.setVisibility(View.GONE);
mMediaController.setEnabled(true);
}
});
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(VideoViewActivity.this,
"Cannot play the video, see logcat for the detailed exception",
Toast.LENGTH_LONG).show();
mProgress.setVisibility(View.GONE);
mMediaController.setEnabled(false);
return true;
}
});
mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
String whatName = "";
switch (what) {
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
whatName = "MEDIA_INFO_BUFFERING_END";
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
whatName = "MEDIA_INFO_BUFFERING_START";
break;
case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
whatName = "MEDIA_INFO_VIDEO_RENDERING_START";
break;
case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
whatName = "MEDIA_INFO_VIDEO_TRACK_LAGGING";
break;
}
Log.d(TAG, "onInfo " + whatName);
return false;
}
});
mVideoView.setOnSeekListener(new MediaPlayer.OnSeekListener() {
@Override
public void onSeek(MediaPlayer mp) {
Log.d(TAG, "onSeek");
mProgress.setVisibility(View.VISIBLE);
}
});
mVideoView.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
Log.d(TAG, "onSeekComplete");
mProgress.setVisibility(View.GONE);
}
});
mVideoView.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG, "onBufferingUpdate " + percent + "%");
}
});
Utils.MediaSourceAsyncCallbackHandler mMediaSourceAsyncCallbackHandler =
new Utils.MediaSourceAsyncCallbackHandler() {
@Override
public void onMediaSourceLoaded(MediaSource mediaSource) {
mMediaSource = mediaSource;
mVideoView.setVideoSource(mediaSource);
mVideoView.seekTo(mVideoPosition);
mVideoView.setPlaybackSpeed(mVideoPlaybackSpeed);
if (mVideoPlaying) {
mVideoView.start();
}
}
@Override
public void onException(Exception e) {
Log.e(TAG, "error loading video", e);
}
};
if(mMediaSource == null) {
// Convert uri to media source asynchronously to avoid UI blocking
// It could take a while, e.g. if it's a DASH source and needs to be preprocessed
Utils.uriToMediaSourceAsync(this, mVideoUri, mMediaSourceAsyncCallbackHandler);
} else {
// Media source is already here, just use it
mMediaSourceAsyncCallbackHandler.onMediaSourceLoaded(mMediaSource);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.videoview, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_slowspeed) {
mVideoView.setPlaybackSpeed(0.2f);
return true;
} else if(id == R.id.action_halfspeed) {
mVideoView.setPlaybackSpeed(0.5f);
return true;
} else if(id == R.id.action_doublespeed) {
mVideoView.setPlaybackSpeed(2.0f);
return true;
} else if(id == R.id.action_quadspeed) {
mVideoView.setPlaybackSpeed(4.0f);
return true;
} else if(id == R.id.action_normalspeed) {
mVideoView.setPlaybackSpeed(1.0f);
return true;
} else if(id == R.id.action_seekcurrentposition) {
mVideoView.pause();
mVideoView.seekTo(mVideoView.getCurrentPosition());
return true;
} else if(id == R.id.action_seekcurrentpositionplus1ms) {
mVideoView.pause();
mVideoView.seekTo(mVideoView.getCurrentPosition()+1);
return true;
} else if(id == R.id.action_seektoend) {
mVideoView.pause();
mVideoView.seekTo(mVideoView.getDuration());
return true;
} else if(id == R.id.action_getcurrentposition) {
Toast.makeText(this, "current position: " + mVideoView.getCurrentPosition(), Toast.LENGTH_SHORT).show();
return true;
} else if(id == R.id.action_reload_source) {
initPlayer();
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mMediaController.isShowing()) {
mMediaController.hide();
} else {
mMediaController.show();
}
}
return super.onTouchEvent(event);
}
@Override
protected void onStop() {
mMediaController.hide();
super.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mVideoView != null) {
mVideoPosition = mVideoView.getCurrentPosition();
mVideoPlaybackSpeed = mVideoView.getPlaybackSpeed();
mVideoPlaying = mVideoView.isPlaying();
// the uri is stored in the base activity
outState.putParcelable("uri", mVideoUri);
outState.putInt("position", mVideoPosition);
outState.putFloat("playbackSpeed", mVideoView.getPlaybackSpeed());
outState.putBoolean("playing", mVideoPlaying);
}
}
}