我已经看到很多有关Android的MediaPlayer问题的问题,其中大部分是由于seekTo()
函数。现在,我尝试使用它,并且它按预期方式工作:糟糕!
此功能似乎非常不一致,尤其是当我们想在视频暂停时提供其功能时。就我而言,我有30到60帧的视频,我想一一播放-MediaMetadataRetriever.getFrameAtTime()不会延迟。
我面临的问题是当我调用seekTo()
时,它不会更新SurfaceView
。它只能在第一次使用,之后SurfaceView
保持不变,就再也不会更新了。
我听说有传言seekTo()
只能以最小1秒钟的间隔运行,但是我用更长的视频进行了测试,并且每秒搜索都不起作用。
代码
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.addCallback(this);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setOnSeekCompleteListener(new OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
// Need this postDelayed(), otherwise the media player always
// returns 0 in getCurrentPosition(), don't know why...
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mMediaPlayer.pause();
}
}, 100);
}
});
mMediaPlayer.setDataSource(localfile_source);
mMediaPlayer.prepare();
// Set the initial position.
mMediaPlayer.start();
mMediaPlayer.seekTo(500);
/**
We're assuming that targetMs is within 0 and the video's duration.
Also, targetMs is calculated to always move to the next/previous frame:
Example: currentMs + ( 1000 / framerate)
(if framerate = 20, then it will exist a frame in each 50ms)
*/
private void seekTo(int targetMs) {
mMediaPlayer.start();
mMediaPlayer.seekTo(targetMs);
}
请注意,由于在暂停视频时使用此功能的已知错误,请使用一种解决方法:
seekTo()
; onSeekComplete()
上。 最佳答案
来自[this question]:
我创建了一些测试代码以尝试使用它。在使用start()
之前,我没有对视频进行seekTo()
编码-我只是在暂停时使用了seekTo()
。
当我以50ms的增量向前移动时,我看到一系列大约4-5帧重复,直到大约2秒钟过去。然后,预览帧集更改为一系列新的4-5帧。这似乎与我以前的试验相吻合,在该试验中,我以2000ms为增量向前移动,并为每个seekTo()
调用看到了一个唯一的帧。
总而言之,当视频暂停时,MediaPlayer似乎会每2秒间隔选择几帧用作预览帧。