Android MediaPlayer寻求错误的位置

时间:2017-04-29 06:46:01

标签: android android-mediaplayer

我使用Android的MediaPlayer播放.mp3文件。此功能应寻求比当前位置大30秒的位置

fun jumpForward() {
            val offset = 30_000
            val old = mMediaPlayer.currentPosition
            val new = if (old + offset < mPlayedBook.duration) old + offset else mPlayedBook.duration
            Log.d("ProgressBar", "PlayerPresenter.rePlayFront, old: $old, new: $new")
            mMediaPlayer.seekTo(new)
        }

但有时进度条的指针会跳到错误的位置。有时甚至倒退。为了跟踪错误的行为,我将日志放入onSeekComplete回调:

override fun onSeekComplete(mp: MediaPlayer) {
    Log.d("ProgressBar", "BookPlayer.onSeekComplete, currentPosition: ${mp.currentPosition / 1000}")
    SystemClock.sleep(200)
    Log.d("ProgressBar", "BookPlayer.onSeekComplete, currentPosition: ${mp.currentPosition / 1000}")
}

这是一个示例日志输出。在这里,我连续几次调用jumpForward()方法:

`04-29 13:36:47.091 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onPrepared, currentPosition: 153
04-29 13:36:47.151 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 127
04-29 13:36:47.361 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 127
04-29 13:36:55.621 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 131, new: 161
04-29 13:36:55.631 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 161
04-29 13:36:55.831 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 100
04-29 13:36:57.071 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 101, new: 131
04-29 13:36:57.091 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 131
04-29 13:36:57.301 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 54
04-29 13:36:58.731 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 56, new: 86
04-29 13:36:58.741 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 86
04-29 13:36:58.941 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 71
04-29 13:37:00.481 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 73, new: 103
04-29 13:37:00.521 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 103
04-29 13:37:00.721 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 85
04-29 13:37:02.251 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 87, new: 117
04-29 13:37:02.281 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 117
04-29 13:37:02.481 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 117
04-29 13:37:03.991 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 118, new: 148
04-29 13:37:04.011 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 148
04-29 13:37:04.211 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 123
04-29 13:37:05.711 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 124, new: 154
04-29 13:37:05.721 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 154
04-29 13:37:05.931 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 128
04-29 13:37:07.571 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 130, new: 160
04-29 13:37:07.591 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 160
04-29 13:37:07.801 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 114
04-29 13:37:09.661 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 116, new: 146
04-29 13:37:09.681 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 146
04-29 13:37:09.881 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 121
04-29 13:37:11.611 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 123, new: 153
04-29 13:37:11.621 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 153
04-29 13:37:11.821 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 127
04-29 13:37:13.501 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 129, new: 159
04-29 13:37:13.511 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 159
04-29 13:37:13.721 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 132
04-29 13:37:15.061 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 133, new: 163
04-29 13:37:15.091 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 163
04-29 13:37:15.291 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 135
04-29 13:37:16.481 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 137, new: 167
04-29 13:37:16.521 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 167
04-29 13:37:16.721 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 104
04-29 13:37:17.691 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 105, new: 135
04-29 13:37:17.701 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 135
04-29 13:37:17.911 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 67
04-29 13:37:18.811 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 68, new: 98
04-29 13:37:18.821 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 98
04-29 13:37:19.031 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 81
04-29 13:37:20.381 27366-27366/ru.orgin.glagol.debug D/ProgressBar: PlayerPresenter.rePlayFront, old: 83, new: 113
04-29 13:37:20.411 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, before delay: 113
04-29 13:37:20.621 27366-27366/ru.orgin.glagol.debug D/ProgressBar: BookPlayer.onSeekComplete, currentPosition, after delay: 56

延迟之前&#39; log正确显示当前位置,因为它应该在seekTo()调用之后。但是在延迟之后&#39;一个(我故意将200毫秒的延迟故意放在一起)经常显示错误的位置,有时甚至是非常错误的。

这是MediaPlayer中的错误还是其他内容?有办法克服这个问题吗?

更新:还有一个问题似乎与各种mp3文件(VBR和CBR)有关。

 override fun onPrepared(mp: MediaPlayer?) {
        isPreparing = false
        isPrepared = true

        mp?.start()
        mp?.seekTo(mProgressSeconds * 1000)
        mp?.setOnBufferingUpdateListener { _, percent ->
            bufferEndPercent = percent.toFloat() / 100
        }
        listeners.forEach { it.onPrepared() }
    }

在这个功能中一切正常。除了在某些设备上,如果mProgressSeconds值超过大约12分钟,MediaPlayer将无法寻找正确的位置并从文件的开头几乎开始播放。

1 个答案:

答案 0 :(得分:0)

在我的案例中,与寻求相关的大多数问题都是由VBR类型的mp3文件引起的。而在CBR 几乎的情况下,一切正常。因此,如果可能的话,解决方案可能是将文件转换为CBR。我用Audacity app完成了它。

更新:在上述问题中与我的更新或多或少相关的主题很少。例如This。但我发现最简单的解决方案是在onPrepared方法中添加一个小延迟:

override fun onPrepared(mp: MediaPlayer) {
    isPreparing = false
    isPrepared = true

    SystemClock.sleep(200)
    mp.start()
    Log.d("progress", "BookPlayer.onPrepared: $mProgressSeconds, currentPosition: ${mp.currentPosition / 1000}")
    mp.seekTo(mProgressSeconds * 1000)

    mp.setOnBufferingUpdateListener { _, percent ->
        bufferEndPercent = percent.toFloat() / 100
    }
    listeners.forEach { it.onPrepared() }
}

似乎onPrepared的调用时间早于实际初始化。所以,在那么小的延迟下,一切都按预期工作了。