简体   繁体   English

Android MediaPlayer试图定位错误

[英]Android MediaPlayer seeks to wrong position

I'm using android's MediaPlayer to play .mp3 files. 我正在使用android的MediaPlayer播放.mp3文件。 This function should seek to position 30 sec greater than the current one 此功能的位置应比当前位置大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)
        }

But sometimes progress bar's pointer jumps to wrong position. 但是有时进度条的指针会跳到错误的位置。 Sometimes even backwards. 有时甚至倒退。 To track the wrong behaviour I put logs in onSeekComplete callback: 为了跟踪错误的行为,我将日志放入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}")
}

And here's an example log output. 这是一个示例日志输出。 Here I'm calling jumpForward() method a few times in a row: 在这里,我连续几次调用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

The 'before delay' log shows current position correctly, as it supposed to be after seekTo() call. “延迟之前”日志正确显示了当前位置,因为它应该在seekTo()调用之后。 But 'after delay' one (I've put that 200 ms delay on purpose) often shows wrong position, sometimes extremely wrong. 但是“延迟后”(我故意将200毫秒延迟)通常显示错误的位置,有时甚至是错误的。

Is this a bug in MediaPlayer or might it be something else? 这是MediaPlayer中的错误,还是其他原因? Is there way to overcome the problem? 有办法解决这个问题吗?

UPDATE: One more issue seems to be related to all kinds of mp3 files (VBR and CBR). 更新:另一个问题似乎与各种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() }
    }

In this function everything works fine. 在此功能中,一切正常。 Except of on some devices, if mProgressSeconds value is more than roughly 12 minutes, MediaPlayer fails to seek to the correct position and starts playing from almost the beginning of the file. 除了某些设备上的值以外,如果mProgressSeconds值大于大约12分钟,则MediaPlayer无法搜索到正确的位置,并几乎从文件的开头开始播放。

Most of the issues related to seeking in my case were caused by VBR type of mp3 files. 在我的情况下,与搜索有关的大多数问题是由mp3文件的VBR类型引起的。 Whereas in case of CBR almost everything worked fine. 而对于CBR, 几乎所有功能都可以正常工作。 So solution to this might be converting files to CBR, if possible. 因此,如果可能的话,解决方案可能是将文件转换为CBR。 I've done it with Audacity app. 我已经使用Audacity应用程序做到了。

Update: There're few topics more or less related to my update in the question above. 更新:在上述问题中,几乎没有与我的更新相关的主题。 This for example. 以这个为例。 But the simplest solution I've found is to add a small delay into onPrepared method: 但是我发现的最简单的解决方案是在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() }
}

It seems like onPrepared is being called a little earlier than it is actually initialized. 似乎onPrepared的调用早于实际初始化的时间。 So, with that small delay everything worked as expected. 因此,在这么小的延迟下,一切都按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM