我已经看到很多关于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()
。答案 0 :(得分:4)
来自[this question]:
"您不能通过使用MediaPlayer API进行逐帧搜索 由Android提供。
如果您真的希望逐帧实施,那么您将拥有 使用第三方多媒体框架,如FFMPEG或您将需要 实施自己的。"
我创建了一些测试代码来试用它。在使用start()
之前,我没有seekTo()
视频 - 我暂停时使用了seekTo()
。
当我以 50ms 为增量向前移动时,我看到一系列约4-5帧重复,直到大约2秒钟过去;然后,预览帧集改变为4-5帧的新系列。这似乎与我以前的试验一致,其中我以 2000ms 的增量向前移动,并为每个seekTo()
电话看到了一个独特的框架。
总之,当视频暂停时,MediaPlayer会在每2秒间隔中选择几个帧作为预览帧。