MediaPlayer seekTo()不会更新SurfaceView

时间:2014-04-23 00:41:56

标签: java android video android-mediaplayer

我已经看到很多关于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()

1 个答案:

答案 0 :(得分:4)

来自[this question]:

  

"您不能通过使用MediaPlayer API进行逐帧搜索   由Android提供。

     

如果您真的希望逐帧实施,那么您将拥有   使用第三方多媒体框架,如FFMPEG或您将需要   实施自己的。"

我创建了一些测试代码来试用它。在使用start()之前,我没有seekTo()视频 - 我暂停时使用了seekTo()

当我以 50ms 为增量向前移动时,我看到一系列约4-5帧重复,直到大约2秒钟过去;然后,预览帧集改变为4-5帧的新系列。这似乎与我以前的试验一致,其中我以 2000ms 的增量向前移动,并为每个seekTo()电话看到了一个独特的框架。

总之,当视频暂停时,MediaPlayer会在每2秒间隔中选择几个帧作为预览帧。