Code example for SurfaceView

Methods: getHeight, getLayoutParams, getWidth, setLayoutParams

0
	 *  
	 * @return 
	 */ 
	protected android.view.ViewGroup.LayoutParams setupAspectRatio() {
		RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) surfaceView
				.getLayoutParams();
 
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		boolean preferPlexAspectRatio = prefs.getBoolean("plex_aspect_ratio",
				false); 
 
		int surfaceViewHeight = surfaceView.getHeight();
		int surfaceViewWidth = surfaceView.getWidth();
 
		float videoWidth = mediaPlayer.getVideoWidth();
		float videoHeight = mediaPlayer.getVideoHeight();
 
		float ratioWidth = surfaceViewWidth / videoWidth;
		float ratioHeight = surfaceViewHeight / videoHeight;
		float aspectRatio = videoWidth / videoHeight;
 
		if (videoHeight == 480 && videoWidth == 720) {
			aspectRatio = (float) 1.78;
		} 
 
		if (preferPlexAspectRatio && this.aspectRatio != null) {
			aspectRatio = Float.parseFloat(this.aspectRatio);
		} 
 
		if (ratioWidth > ratioHeight) {
			lp.width = (int) (surfaceViewHeight * aspectRatio);
			lp.height = surfaceViewHeight;
		} else { 
			lp.width = surfaceViewWidth;
			lp.height = (int) (surfaceViewWidth / aspectRatio);
		} 
 
		if (lp.width > surfaceViewWidth) {
			lp.width = surfaceViewWidth;
		} 
 
		if (lp.height > surfaceViewHeight) {
			lp.height = surfaceViewHeight;
		} 
 
		return lp;
	} 
 
	public void surfaceDestroyed(SurfaceHolder holder) {
		if (!mediaplayer_released) {
			mediaPlayer.release();
			mediaplayer_released = true;
		} 
	} 
 
	@Override 
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.video_playback); 
		init(); 
	} 
 
	/** 
	 * Initialize the mediaplayer and mediacontroller. 
	 */ 
	protected void init() { 
		Bundle extras = getIntent().getExtras();
 
		videoURL = extras.getString("videoUrl");
		if (videoURL == null) {
			videoURL = extras.getString("encodedvideoUrl");
			if (videoURL != null) {
				videoURL = URLDecoder.decode(videoURL);
			} 
		} 
		videoId = extras.getString("id");
		String summary = extras.getString("summary");
		String title = extras.getString("title");
		String posterURL = extras.getString("posterUrl");
		aspectRatio = extras.getString("aspectRatio");
		String videoFormat = extras.getString("videoFormat");
		String videoResolution = extras.getString("videoResolution");
		String audioFormat = extras.getString("audioFormat");
		String audioChannels = extras.getString("audioChannels");
		resumeOffset = extras.getInt("resumeOffset");
		duration = extras.getInt("duration");
 
		mediaPlayer = new MediaPlayer();
		mediaPlayer.setOnErrorListener(new SerenityOnErrorListener());
		surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
		surfaceView.setKeepScreenOn(true);
		SurfaceHolder holder = surfaceView.getHolder();
		holder.addCallback(this);
		holder.setSizeFromLayout();
 
		mediaController = new MediaController(this, summary, title, posterURL,
				videoResolution, videoFormat, audioFormat, audioChannels);
		mediaController.setAnchorView(surfaceView);
		mediaController.setMediaPlayer(new SerenityMediaPlayerControl());
	} 
 
	@Override 
	public void finish() { 
		super.finish(); 
		progressReportinghandler.removeCallbacks(progressRunnable);
	} 
 
	@Override 
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (mediaController.isShowing()) {
			if (keyCode == KeyEvent.KEYCODE_BACK) {
				mediaController.hide();
 
				if (isMediaPlayerStateValid() && mediaPlayer.isPlaying()) {
					mediaPlayer.stop();
				} 
				return super.onKeyDown(keyCode, event);
			} 
		} else { 
			if (keyCode == KeyEvent.KEYCODE_BACK) {
				if (isMediaPlayerStateValid() && mediaPlayer.isPlaying()) {
					mediaPlayer.stop();
				} 
				return super.onKeyDown(keyCode, event);
			} 
		} 
 
		if (keyCode == KeyEvent.KEYCODE_INFO) {
			if (isMediaPlayerStateValid()) { 
				if (mediaController.isShowing()) {
					mediaController.hide();
				} else { 
					mediaController.show(CONTROLLER_DELAY);
				} 
			} 
			return true; 
		} 
 
		if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
				|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE
				|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
			if (isMediaPlayerStateValid() && mediaPlayer.isPlaying()) {
				mediaPlayer.pause();
				mediaController.show(CONTROLLER_DELAY);
				progressReportinghandler.removeCallbacks(progressRunnable);
			} else { 
				mediaPlayer.start();
				mediaController.hide();
				progressReportinghandler.postDelayed(progressRunnable, 5000);
			} 
			return true; 
		} 
 
		if ((keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD || keyCode == KeyEvent.KEYCODE_MEDIA_NEXT)
				&& isMediaPlayerStateValid()) { 
			int skipOffset = 10000 + mediaPlayer.getCurrentPosition();
			int duration = mediaPlayer.getDuration();
			if (skipOffset > duration) {
				skipOffset = duration - 1;
			} 
			if (!mediaController.isShowing()) {
				mediaController.show(CONTROLLER_DELAY);
			} 
			mediaPlayer.seekTo(skipOffset);
			return true; 
		} 
 
		if ((keyCode == KeyEvent.KEYCODE_MEDIA_REWIND || keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS)
				&& isMediaPlayerStateValid()) { 
			int skipOffset = mediaPlayer.getCurrentPosition() - 10000;
			if (skipOffset < 0) {
				skipOffset = 0;
			} 
			if (!mediaController.isShowing()) {
				mediaController.show(CONTROLLER_DELAY);
			} 
			mediaPlayer.seekTo(skipOffset);
			return true; 
		} 
 
		if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP && isMediaPlayerStateValid()) {
			if (mediaPlayer.isPlaying()) {
				mediaPlayer.pause();
				if (!mediaController.isShowing()) {
					mediaController.show(CONTROLLER_DELAY);
				} 
			} 
			return true; 
		} 
 
		return super.onKeyDown(keyCode, event);
	} 
 
	protected boolean isMediaPlayerStateValid() { 
		if (mediaPlayer != null && mediaplayer_error_state == false
				&& mediaplayer_released == false) {
			return true; 
		} 
		return false; 
	} 
 
	@Override 
	protected void onStart() { 
		super.onStart(); 
		EasyTracker.getInstance().activityStart(this);
	} 
 
	@Override 
	protected void onStop() { 
		super.onStop(); 
		EasyTracker.getInstance().activityStop(this);
	} 
 
	/** 
	 * A simple media player control. Handles the main events that can occur 
	 * while using the player to play a video. 
	 *  
	 * @author dcarver 
	 *  
	 */ 
	protected class SerenityMediaPlayerControl implements MediaPlayerControl { 
		public void start() { 
			mediaPlayer.start();
		} 
 
		public void seekTo(long pos) {
			mediaPlayer.seekTo((int) pos);
		} 
 
		public void pause() { 
			mediaPlayer.pause();
		} 
 
		public boolean isPlaying() { 
			return mediaPlayer.isPlaying();
		} 
 
		public long getDuration() { 
			return mediaPlayer.getDuration();
		} 
 
		public long getCurrentPosition() { 
			return mediaPlayer.getCurrentPosition();
		} 
 
		public int getBufferPercentage() { 
			return 0; 
		} 
 
		public boolean canSeekForward() { 
			return true; 
		} 
 
		public boolean canSeekBackward() { 
			return true; 
		} 
 
		public boolean canPause() { 
			return true; 
		} 
	} 
 
	/** 
	 * A task that updates the watched status of a video. 
	 *  
	 * @author dcarver 
	 *  
	 */ 
	protected class WatchedVideoRequest extends AsyncTask<Void, Void, Void> {
 
		protected String scrobbleKey;
 
		public WatchedVideoRequest(String key) {
			scrobbleKey = key;
		} 
 
		@Override 
		protected Void doInBackground(Void... params) {
			PlexappFactory factory = SerenityApplication.getPlexFactory();
			factory.setWatched(scrobbleKey);
			return null; 
		} 
	} 
 
	/** 
	 * A task that updates the progress position of a video while it is being 
	 * played. 
	 *  
	 * @author dcarver 
	 *  
	 */ 
	protected class UpdateProgressRequest extends AsyncTask<Void, Void, Void> {
 
		@Override 
		protected Void doInBackground(Void... params) {
			PlexappFactory factory = SerenityApplication.getPlexFactory();
			if (isMediaPlayerStateValid() && mediaPlayer.isPlaying()) {
				String offset = Integer.valueOf(
						mediaPlayer.getCurrentPosition()).toString();
				factory.setProgress(videoId, offset);
			} 
			return null; 
		} 
	} 
	 
	protected class CompletedVideoRequest extends AsyncTask<Void, Void, Void> {
		 
		private String uvideoId;
		public CompletedVideoRequest(String videoId) {
			uvideoId = videoId;
		} 
 
		/* (non-Javadoc) 
		 * @see android.os.AsyncTask#doInBackground(Params[]) 
		 */ 
		@Override 
		protected Void doInBackground(Void... params) {
			PlexappFactory factory = SerenityApplication.getPlexFactory();
			factory.setProgress(uvideoId, "0");
			return null; 
		} 
		 
	} 
 
	/** 
	 * A prepare listener that handles how a video should start playing. 
	 *  
	 * It checks to see if the video has been previously viewed and if so will 
	 * present a dialog to allow resuming of a video from where it was 
	 * previously last viewed. Otherwise it will start play back of the video. 
	 * It also launches the Watched status update task and the progress update 
	 * handler. 
	 *  
	 * @author dcarver 
	 *  
	 */ 
	protected class VideoPlayerPrepareListener implements OnPreparedListener {
 
		private Context context;
 
		public VideoPlayerPrepareListener(Context context) {
			this.context = context;
		} 
 
		public void onPrepared(MediaPlayer mp) {
			android.view.ViewGroup.LayoutParams lp = setupAspectRatio();
			surfaceView.setLayoutParams(lp);
			mediaController.setEnabled(true);
 
			if (resumeOffset > 0) {
				AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
						context, android.R.style.Theme_Holo_Dialog);