编辑:
显然这与多个 Activity 无关,而与视频文件的编码有关。
我将尝试简化问题:我有一个处于暂停状态的 MediaPlayer 对象,当我调用 mediaPlayer.getCurrentPosition()
时,我得到了一个准确的结果。当我在此对象上调用 mediaPlayer.setSurface()
(使用不同的表面)然后调用 mediaPlayer.play()
时,视频的播放位置与返回的位置不同通过 getCurrentPosition()。我正在对 API >= ICE_CREAM_SANDWICH 进行测试。
- 使用项目中的本地资源和通过网络流进行测试,结果:没有区别。
视频文件链接:http://wpc.4ba9.edgecastcdn.net/804BA9/testenvmedia/m_8705_LuS3w7ctSZjB.mov.bs.mp4
我有两个 Activity ,Activity-A 和 Activity-B。
Activity-A 使用 MediaPlayer
将视频从远程流播放到 TextureView
,
它还包含一个按钮,其目的是:
调用 mediaPlayer.pause();
打开 Activity-B。
Activity-B 还包含一个 TextureView
,它应该使用相同的 MediaPlayer
对象在其当前位置播放相同的视频。
Activity-A onCreate方法:
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方法:
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 输出:
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
因此,尽管 MediaPlayer 似乎要从那个确切位置恢复,但我对不同的视频有不同的行为,每次我尝试在 Activity-B 中播放视频时,大多数视频都从完全相同的帧开始,一个视频从一开始就开始,其他视频每次都从其他时间点开始。
来自 Android 的 MediaPlayer.SetSurface()
方法文档:
这个方法可以在任何状态下调用,调用它不会改变对象状态。
如有任何帮助,我们将不胜感激。 谢谢!
最佳答案
看来你的问题出在这个特定的视频上,更多的关键帧将有助于播放器更准确地恢复播放。
再次尝试重新编码,使用 ffmpeg 和 libx264 尝试添加这些参数:
-g=25 -keyint_min=25
关于Android 的 MediaPlayer setSurface 在暂停状态下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19299412/