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.
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:
Call mediaPlayer.pause();
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!
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With