【问题标题】:android mediaplyer seekTo inside onPreparedandroid mediaplayer seekTo 里面 unPrepared
【发布时间】:2013-04-09 09:19:34
【问题描述】:

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

我走这种方式空闲状态 -> 初始化状态 -> prepareAsync() -> 并在 onPrepared 中调用了 seekTo,但在这个 android 版本上,媒体播放器返回

“尝试查找文件末尾:request = {int>0}, durationMs = 0”

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

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

您认为这是一个媒体播放器错误还是有更好的地方可以调用 seekTo ?或者可能是一种如何知道 seekTo 失败的方法?如果当前位置小于所需位置,我想避免定期检查当前位置,并尝试调用 seek to,因为这种方法有很多不同的问题。

这是一个流畅的流媒体视频内容

【问题讨论】:

    标签: android media-player seek


    【解决方案1】:

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

    在 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();
            }
        }
    }
    

    (我个人不喜欢使用布尔值守卫,但是如果您查看随 sdk 提供的媒体播放器示例,它会执行类似的操作)。

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

    如果有人有适用于所有操作系统版本的更好解决方案,我很乐意听到。

    【讨论】:

    • 继 Robin 的回答之后,我尝试将媒体播放器源代码跟踪到最终设置持续时间值的位置。我最终查看了 StageFrightPlayer 类,它有一个 AwesomePlayer 结构,它似乎将值保存在其 mDurationUs 成员中。这似乎是在调用 initAudioDecoder 或 initVideoDecoder 时设置的。我想理想的解决方案会导致调用这两个函数之一而无需调用 java MediaPlayer.start() 函数?
    • 我也刚刚将此信息添加为 Android Issue 54112 的评论。
    【解决方案2】:

    这是 NuPlayer 实现的问题。 NuPlayer 没有适当的准备状态实现,这与使用 AwesomePlayer 的本地播放不同。仅当调用 start() 时才建立网络连接,之后知道持续时间。如果duration为0,可以绕过duration检查来解决这个问题,我之前试过了。

    【讨论】:

      【解决方案3】:

      这里是源代码:

      418 status_t MediaPlayer::seekTo_l(int msec)
      419 {
      420     ALOGV("seekTo %d", msec);
      421     if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
      422         if ( msec < 0 ) {
      423             ALOGW("Attempt to seek to invalid position: %d", msec);
      424             msec = 0;
      425         } else if ((mDuration > 0) && (msec > mDuration)) {
      426             ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration);
      427             msec = mDuration;
      428         }
      429         // cache duration
      430         mCurrentPosition = msec;
      431         if (mSeekPosition < 0) {
      432             getDuration_l(NULL);
      433             mSeekPosition = msec;
      434             return mPlayer->seekTo(msec);
      435         }
      436         else {
      437             ALOGV("Seek in progress - queue up seekTo[%d]", msec);
      438             return NO_ERROR;
      439         }
      440     }
      441     ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState);
      442     return INVALID_OPERATION;
      443 }
      

      我建议你先调用 getDuration() 让媒体播放器实例强制初始化持续时间字段。 否则,请尝试在 seekTo() 之前调用 start(),甚至在 start() 之后的某个时间调用 seekTo()。

      【讨论】:

      • 感谢您的回复,不幸的是在 seekTo 之前调用 getDuration() 没有帮助,在 seekTo() 之前调用 start() 也没有帮助,并且延迟调用 seekTo 不是一个可靠的解决方案。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多