我已经看到很多有关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秒间隔选择几帧用作预览帧。

    10-06 16:14