MediaPlayer skips forward about 6 seconds on rotation

后端 未结 2 536
南方客
南方客 2020-12-24 10:10

I have a MediaPlayer in a Fragment which retains its instance on configuration changes. The player is playing a video loaded from my assets directory. I have the scenario

相关标签:
2条回答
  • 2020-12-24 10:20

    Thanks to natez0r's answer, I have managed to get the setup described working. However, I use a slightly different method. I'll detail it here for reference.

    I have one Fragment which I flag to be retained on configuration changes. This fragment handles both the media playback (MediaPlayer), and the standard TextureView (which provides the SurfaceTexture where the video buffer gets dumped). I initialize the media playback only once my Activity has finished onResume() and once the SurfaceTexture is available. Instead of subclassing TextureView, I simply call setSurfaceTexture (since it's public) in my fragment once I receive a reference to the SurfaceTexture. The only two things retained when a configuration change happens are the MediaPlayer reference, and the SurfaceTexture reference.

    I've uploaded the source of my sample project to Github. Feel free to take a look!

    0 讨论(0)
  • 2020-12-24 10:20

    I know this question is a tad old now, but I was able to get this working in my app without the skipping. The issue is the surface getting destroyed (killing whatever buffer it had in it). This may not solve all your issues because it targets API 16, but you can manage your own SurfaceTexture inside your custom TextureView where the video is drawn:

    private SurfaceTexture mTexture;
    
        private TextureView.SurfaceTextureListener mSHCallback =
                new TextureView.SurfaceTextureListener() {
                    @Override
                    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
                            int height) {
                        mTexture = surface;
                        mPlayer.setSurface(new Surface(mTexture));
                    }
    
                    @Override
                    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
                            int height) {
                        mTexture = surface;
                    }
    
                    @Override
                    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                        mTexture = surface;
                        return false;
                    }
    
                    @Override
                    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
                        mTexture = surface;
                    }
                };
    

    the key is returning false in onSurfaceTextureDestroyed and holding onto mTexture. When the view gets re-attached to the window you can set the surfaceTexture:

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            if (mTexture != null) {
                setSurfaceTexture(mTexture);
            }
        }
    

    This allows my view to continue playing video from EXACTLY where it left off.

    0 讨论(0)
提交回复
热议问题