我的问题似乎只在android 4.2.2上发生

我以这种方式进入空闲状态->初始化状态-> prepareAsync()->并在onPrepared中调用seekTo,但是在此android版本上,mediaplayer返回

“试图搜寻文件的结尾:request = {int> 0},durationMs = 0”

并从头开始播放,因为我无法捕捉到这一点,也没有任何监听器,它只会将此消息写入日志,我无法对此做出真正的 react 。

更奇怪的是,如果我在onPrepared()中调用mediaPlayer.getDuration(),它将返回正确的值而不是0。

您是否认为这是媒体播放器错误,还是有更好的地方可以致电seekTo?或者也许是一种如何知道seekTo失败的方法?我想避免定期检查当前位置是否小于期望位置,并尝试调用“搜索到”,因为这种方法存在很多不同的问题。

这是流畅的视频流内容

最佳答案

我目前正在尝试找到解决同一问题的方法。到目前为止,我想出的最好的方法如下。

在4.2上,我注意到已收到以下回叫:

1)onVideoSizeChanged()-高度和宽度= 0
2)onPrepared()
3)onVideoSizeChanged()-适当的高度和宽度

您尚未准备好播放器,因此无法在(1)中调用seekTo。

如您所述,如果您在(2)中调用seekTo,则媒体播放器将生成警告“试图搜索到文件末尾”

仅当调用MediaPlayer.start()时,您才会收到(3),但是此时您可以成功调用seekTo()。

MediaPlayer mMediaPlayer = new MediaPlayer(); // + some initialisation code
boolean mVideoSizeIsSet = false;
boolean mMediaPlayerIsPrepared = false;

public void onPrepared(MediaPlayer mediaplayer) {
    Log.d(TAG, "onPrepared called");
    mMediaPlayerIsPrepared = true;

    if (mVideoSizeIsSet) {
        mMediaPlayer.seekTo();
    }

    mMediaPlayer.start()
}


public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
    Log.d(TAG, "onVideoSizeChanged called");

    if (width == 0 || height == 0) {
        Log.d(TAG, "invalid video width(" + width + ") or height(" + height + ")");
    } else {

        mVideoSizeIsSet = true;

        if (mMediaPlayerIsPrepared) {
            mMediaPlayer.seekTo();
        }
    }
}

(我个人不喜欢使用 bool 值保护器,但是如果您看一下sdk附带的媒体播放器示例,它会执行类似的操作)。

通过对一系列设备/操作系统版本进行测试,可以提供通用的解决方案。但是,4.2版存在一个错误。调用mMediaPlayer.start()似乎会导致视频的前几帧在seekTo()发生之前开始播放,这对我来说几乎是不可见的,但对您来说可能更可见。我目前正在以某种方式隐藏我的表面 View ,直到收到onSeekComplete()事件为止,但这并不理想。

如果有人有一个适用于所有OS版本的更好的解决方案,我希望听到它。

10-08 12:31