9

Is there anyway that you can make the application keeps the buffer after orientation without manually handling the configuration changes.

The scenario basically:

  1. Video buffer up until the latest point should be preserved when the orientation changes.

  2. Need to reload a new layout (because portait and lanscape has different layout), Therefore letting the app restart the activity to reload new resources is the best way I think.

  3. The video component is in a fragment.

Alternatives that I tried but are not acceptable:

  1. The first work around is to save the position of the video and after the view has been created, use seekTo to go to the last point. However, this will cause the device to re-buffer again.

  2. I'd tried playing around with fragment setRetainInstance(true) and ensure the media player is not reinitialize after orientation changes. After each onCreateView, I just set the mediaplayer.setDisplay() to a new surfaceholder. Unfortunately this cause the media player to go into error state which in turn requires the media player to be reseted.

Any suggestion / workaround for this?

Edited: I saw somewhere in stackoverflow that you can change the mediaplayer surface holder while the mediaplayer is active in android 4.0+. However, I am developing an app for android 3.x.

Maziz
  • 322
  • 2
  • 13
  • See if my answer [here](http://stackoverflow.com/questions/9987042/videoview-onresume-loses-buffered-portion-of-the-video/10368107#10368107) helps. – yorkw May 21 '12 at 03:09
  • @yorkw but this means hacking down the android.jar. Right? Any way you know to do it for the mainstream? And also to make sure the Play Store will accept it? – nembleton May 21 '12 at 03:32
  • 1
    Either hack a copy of VideoView (not the actual android.jar) or build your own VideoView from MediaPlayer, the key point here is to properly avoid the method call which cause re-buffer or clean buffer during configuration change (more preciously, in both activity's life cycle callback methods and SurfaceHolder callback methods). – yorkw May 21 '12 at 03:45
  • Im using Media Player in a fragment and I'm curious with you second answer.Does the activity get restarted? If it does, then each time the activity will re-initialize the activity and will cause the surfaceview to be reinit. If the media player is in pause state at that time, calling mediaplayer.start() will throw itself into Error state. Since I'm putting the video in fragment, I've tried 2 scenarios, reinit surfaceview and not. When I reinit, it throws into error state, when I'm not, nothing will be displayed because no view is drawn. – Maziz May 21 '12 at 04:12
  • @Maziz, how about callign invalidate() or requestLayout() on your view? Does it fixes your "no view is drawn" problem? – nembleton May 21 '12 at 04:20
  • Sorry, the view is drawn. The reason it didn't display anything because it is in paused state. However, when I change the code so that It will start playing after the orientation had been change, calling the mediaplayer to start will throw itself into error state. My media player still store the previous surfaceholder even after the fragment had call onCreateView. – Maziz May 21 '12 at 04:36
  • @Maziz, That is why I have mentioned earlier that you need take care of re-buffer and clean buffer call properly not only in Activity callback but also in SurfaceHolder callback, that is, prepare media at very first time surfaceCreated() involved and release media at very last time surfaceDestroyed() involved, and use a boolean state variable avoid literately prepare/release call in between (when surfaceCreated() and surfaceDestroyed() is triggered due to configuration change). – yorkw May 21 '12 at 04:46
  • @yorkw, I've check my code. Each time after the surface has been re-init in onCreateView, it will try to play (without releasing the media player or re-initialize it) and when it plays, it will throw into error state. – Maziz May 21 '12 at 09:12
  • @Maziz, post some code may make more sense for others investigate your problem. – yorkw May 21 '12 at 09:42

3 Answers3

0

I think you can override onConfigurationChanged() and do re-layout programatically.

You can modify layout without touching video.

lulumeya
  • 1,619
  • 11
  • 14
  • Thanks for the answer. It's just not feasible to relayout when there's a lot of components involved. – Maziz May 21 '12 at 04:17
  • 1
    Then how about use separate Fragment to layout and video view? – lulumeya May 21 '12 at 04:22
  • 1
    You mean 1 Fragment will display the view and another one will be aretained fragment? Doing so will cause the media player in the retained fragment to be thrown into error state because the surfaceview had been changed. – Maziz May 21 '12 at 04:37
0

Maybe it is late for you but there can be others facing same problem. You can use second option. if you do not set the display of MediaPlayer to null before destroying the view of fragment, when you access to mediaplayer again it is running into error state. My solution was implementing surfaceCreated and surfaceDestroyed events of surfaceholder.

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mediaPlayer.setDisplay(holder);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    mediaPlayer.setDisplay(null);
}
0

I don't think its possible to keep the buffer while rotating in android without using the android:configChanges flags. These are the available options:

  1. Allow rotation and activity recreation but save the video position. This will loose the buffer but will allow you to continue from the last position. This does not work with live streams, only for local files or remote VOD. You will have to save your position in onSaveInstanceState and restore it in onCreate for an activity/fragment. Or keep the value using setRetainInstance(true) but this last option is not recommended.

  2. Use the android:configChanges="orientation|screenSize" flags and manage yourself the UI size change. Have a look at this POC as a reference: https://github.com/caspercba/POCMediaPlayerRotation

  3. Go for a third party player like NexStreaming.

Cheers

Gaspar de Elias
  • 244
  • 3
  • 12