How do you handle rotation with video playback?


#1

Hi! I’m new to the forum. I bought the book about a month ago and I’m enjoying it so far. However, I’ve a question regarding this chapter(maybe?) and the video playback challenge of the prior chapter.

In general, how do you handle rotation on video playback using MediaPlayer and a SurfaceHolder? I’m using setRetainInstance(true) and that seems to be insufficient for the job. To clarify, I’m playing a random mp4 file. On rotation, the playback seems to just stop.

I’m aware that OnSurfaceDestroyed() and OnSurfaceChanged() are called in the SurfaceHolder.Callback. Does this play into the equation for the solution? I’m aware that the callbacks are called but I’m uncertain as to how they effect playback.


#2

Hmm, I was going to say “check out the documentation for VideoView”, but it’s not there for some unknown reason.

The answer is that you must modify your activity so that it can handle configuration changes. That will prevent the activity from being destroyed on rotation. Check out the documentation for the “configChanges” attribute on the tag.

(Why don’t we normally recommend this, you may ask? Two reasons - oftentimes the layout system does not play well with this tactic, and it also makes it difficult to customize your display for different orientations.)


#3

I was able to get the MediaPlayer to ‘resume’ playing the video using surfaceCreated() and surfaceDestroyed(). During the rotation, the MediaPlayer still plays the movie, it does not pause.

This is a simple and effective way to retain the movie during rotation.

	      @Override
	      public void surfaceCreated(SurfaceHolder surfaceHolder)
	      {
	    	  if (mPlayer == null)
	         {
                       // init code here
                       ....
	    	 }
	    	 else 
	    	 {
	    		 // restablish connection to passed in surfaceHolder 
	    		 mPlayer.setDisplay(surfaceHolder);
	    	 }
	      }

	      @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
	    	      // disengage old surface holder
                      mPlayer.setDisplay(null);
	      }

#4

My solution to the video challenge involved displaying the video within a DialogFragment. I tried using setRetainInstance(true) to keep it around after rotation, but like namnguyen, my video is simply destroyed and stops playing.

I tried AntonyBurt’s suggested updates to the surfaceDestroyed and surfaceCreated methods, but now the app simply crashes when I rotate while playing the video.

What can be done to keep a dialog and its surface retained during rotation?


#5

Thanks Anthony but unfortunately it is not working.

Here is what is happening on my Nexus 5:

  1. Start application
  2. click on “Play Video” to play the mp4 clip
  3. Video starts playing but there is no picture, just tone
  4. Rotate device, and now video shows but starts from the very beginning
  5. Rotate back, video still showing and continuing properly but starts from the very beginning
  6. Click back returns to the MoonActivity with picture and buttons on it but the video is still playing in background (you can hear it but not see it)

Has anyone been able to resolve the rotation change issue while playing the video?

Much appreciated,


#6

i coded playing of the video in a separate Activity and Fragment. I found that simply entering the following one line in the AndroidManifest tag for the video-playing Activity allowed the video to play uninterrupted through device rotations:

The Android Developer docs say that using the configChanges attribute should be avoided and used only as a last resort. This attribute prevents the Activity from getting killed upon a screen rotation; Android leaves to the application the task of dealing with the configuration change by overriding the onConfigurationChanged() method. Although the Developer docs say that it’s generally necessary to retrieve and rework all the app’s resources, including layouts and drawables, to correctly deal with the configuration change, I didn’t have to do anything with onConfigurationChanged() to make things work reasonably well.