Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android's MediaPlayer setSurface while on paused state

EDIT:

So apparently this has nothing to do with multiple activities, and this has something to do with the encoding of the video file.

I will try to simplify the question: I have a MediaPlayer object in a paused state, when I call mediaPlayer.getCurrentPosition() I get a result which is accurate. When I call mediaPlayer.setSurface() (using a different surface) followed by mediaPlayer.play() on this object the video is played in a different position than the one returned by getCurrentPosition(). I am testing on API >= ICE_CREAM_SANDWICH.

  • Tested both using a local resource in the project and via network stream, result: no difference.

Link to video file: http://wpc.4ba9.edgecastcdn.net/804BA9/testenvmedia/m_8705_LuS3w7ctSZjB.mov.bs.mp4


I have two activities, Activity-A and Activity-B.

Activity-A plays video from a remote stream to a TextureView using a MediaPlayer, it also holds a button, who's purpose is to:

  1. Call mediaPlayer.pause();

  2. Open Activity-B.

Activity-B holds also a TextureView which is supposed to play the same video at it's current location using the same MediaPlayer object.

Activity-A onCreate method:

    textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {        
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int w, int h) {
            try {
                final MediaPlayer mediaPlayer = MyApplication.getMediaPlayer();
                mediaPlayer.setDataSource(context, videoURI);
                mediaPlayer.setSurface(new Surface(surfaceTexture));
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setLooping(shouldLoop);
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mp.start();
                    }
                });

                mediaPlayer.prepareAsync();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
    });

    btnFullScreen.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {     
        Log.e("WHATEVER", ">>> pause video at " + MyApplication.getMediaPlayer().getCurrentPosition());
        MyApplication.getMediaPlayer().pause();
        Intent intent = new Intent(getActivity(), ActivityB.class);
        startActivity(intent);
    }});

Activity-B onCreate method:

        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int w, int h) {
            MediaPlayer mediaPlayer = MyApplication.getMediaPlayer();
            mediaPlayer.setSurface(new Surface(surface));

            Log.e("WHATEVER", ">>> resume video at " + mediaPlayer.getCurrentPosition());
            mediaPlayer.start();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        }
    });

LogCat output:

10-10 17:33:15.966  13886-13886/com.whatever.android.debug E/WHATEVER﹕ >>> pause video at 1958
10-10 17:33:16.817  13886-13886/com.whatever.android.debug E/WHATEVER﹕ >>> resume video at 1958

So even though it seems like the MediaPlayer is going to resume from that exact position, I get different behaviour for different videos, most of them start at the exact same frame every time I try to play those in Activity-B, one video starts at the very beginning, other one starts at some other point every time.

From Android's documentation of MediaPlayer.SetSurface() method:

This method can be called in any state and calling it does not change the object state.

Any help would be greatly appreciated. Thanks!

like image 547
woot Avatar asked Oct 10 '13 15:10

woot


1 Answers

it seems your problem is with this specific video, more keyframes will help the player to resume the playing more accurately.

try to re-encode again, with ffmpeg and libx264 try adding these parameters:

-g=25 -keyint_min=25
like image 137
eluzix Avatar answered Sep 21 '22 15:09

eluzix