【发布时间】:2014-05-02 00:13:21
【问题描述】:
我已经看到很多关于 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()上暂停。
【问题讨论】:
-
SurfaceView似乎有很多错误。如果您的应用仅支持 4.0+,那么您可以尝试使用TextureView而不是SurfaceView。 -
您要使用什么类型的媒体?视频通常不仅仅是一系列图像。有多种帧类型,但并非所有帧类型都提供了开始播放的基础......这意味着如果没有一些不准确或一些处理,您就无法找到它们。
-
是手机摄像头录制的.mp4视频。问题不在于不准确或处理时间,它只是没有显示任何内容。
-
请查看我更新的答案。
标签: java android video android-mediaplayer