我在Galaxy Tab 3的Android 4.4上播放视频时遇到问题。以前的Android 4.2版本没有出现此问题。
问题
我正在循环播放视频。这对所有用户来说都很有效,直到Tab 3更新到Android 4.4。从那时起,视频在第一个循环后冻结(准确地说,它被卡在视频的第一帧上)。
我可以重现这种行为,在视频冻结的那一刻,我的LogCat开始充满以下输出:
16:25:25.239 14589-14601/my.app V/MediaPlayer? back from callback
16:25:25.499 14589-14686/my.app V/MediaPlayer? message received msg=7, ext1=0, ext2=0
16:25:25.499 14589-14686/my.app V/MediaPlayer? unrecognized message: (7, 0, 0)
16:25:25.499 14589-14686/my.app V/MediaPlayer? callback application
16:25:25.499 14589-14686/my.app V/MediaPlayer? back from callback
16:25:25.519 14589-14602/my.app V/MediaPlayer? message received msg=4, ext1=0, ext2=0
16:25:25.519 14589-14602/my.app V/MediaPlayer? Received seek complete
16:25:25.519 14589-14602/my.app V/MediaPlayer? All seeks complete - return to regularly scheduled program
16:25:25.519 14589-14602/my.app V/MediaPlayer? callback application
16:25:25.519 14589-14602/my.app V/MediaPlayer? back from callback
16:25:25.519 14589-14601/my.app V/MediaPlayer? message received msg=6, ext1=0, ext2=0
16:25:25.519 14589-14601/my.app V/MediaPlayer? Received MEDIA_STARTED
16:25:25.519 14589-14601/my.app V/MediaPlayer? callback application
16:25:25.519 14589-14601/my.app V/MediaPlayer? back from callback
16:25:25.789 14589-14686/my.app V/MediaPlayer? message received msg=7, ext1=0, ext2=0
16:25:25.789 14589-14686/my.app V/MediaPlayer? unrecognized message: (7, 0, 0)
16:25:25.789 14589-14686/my.app V/MediaPlayer? callback application
16:25:25.789 14589-14686/my.app V/MediaPlayer? back from callback
16:25:25.809 14589-14602/my.app V/MediaPlayer? message received msg=4, ext1=0, ext2=0
16:25:25.809 14589-14602/my.app V/MediaPlayer? Received seek complete
代码
下面(简单)的活动应该播放视频。永远不会调用MediaPlayer.OnErrorListener()和MediaPlayer.OnInfoLister()。
public class VideoActivity extends Activity {
private MediaPlayer mediaPlayer;
private String videoPath = "some path obtained from the system";
// [...]
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mediaPlayer = new MediaPlayer();
startMovie();
}
private void startMovie(){
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setLooping(true);
mediaPlayer.setDataSource(videoPath);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mp.start();
mp.seekTo(0);
}
});
mediaPlayer.prepare();
}
}
在活动期间,视频可以使用不同的视频文件路径启动多次,这就是为什么我在启动电影之前停止并重置播放器的原因。
到目前为止,我在互联网上找到的唯一解决方案是确保MediaPlayer不会被GC收集(我通过不将其作为方法本地对象来做到这一点),并实现WakeLock,我也这样做了,但没有效果。
有人能在这里帮我指一下正确的方向吗?非常感谢。
与其说是解决方案,不如说是一种变通方法,我最终使用MediaPlayer
的setLooping
方法来循环视频。相反,我现在在MediaPlayer
的OnCompletion
回调中重新启动视频。经过大量的尝试,这是我让它在我正在测试的所有设备上工作的唯一方法
public class VideoActivity extends Activity {
private MediaPlayer mediaPlayer;
private String videoPath = "some path obtained from the system";
// [...]
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mediaPlayer = new MediaPlayer();
startMovie();
}
private void startMovie(){
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setDataSource(videoPath);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mp.start();
mp.seekTo(0);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
startMovie();
}
});
mediaPlayer.prepare();
}
}
尽管如此,如果有人对这个问题有一个有效的解决方案,我会很乐意将相应的答案标记为正确的。