Android MediaPlayer seekTo() / getDuration() 未按预期工作
Android MediaPlayer seekTo() / getDuration() not working as expected
我正在使用 android MediaPlayer 库播放一些 MP3 文件。我不负责这些文件,无论如何也无法更改它们,只能播放它们。
我目前更新了一个关于用户当前完成文件的进度条,将进度条的最大值设置为 mediaPlayer.getDuration()
。我知道这个返回的值是正确的。我每 500 毫秒 postDelayed 一个 Runnable,用 mediaPlayer.getCurrentPosition
的值更新进度条。这一切都按预期正常工作。
当我尝试使用 seekTo 方法时出现问题(但偶尔它会像我预期的那样工作)。我创建的媒体播放器对象注册了一个 OnSeekCompleteListener。当我调用 mediaPlayer.seekTo(50000)
时,使用 mediaPLayer.getCurrentPosition()
在 OnSeekCompleteListener 中输出的值是我告诉它要查找的正确值(在本例中为 51000,假设我们从 1000 毫秒开始进入文件)。但是,当 postDelayed runnable 运行以更新进度条时,mediaPlayer.getCurrentPosition()
返回的值通常(95% 的时间)远低于 OnSeekCompleteListener 中输出的值。
最终返回的值似乎没有任何韵律或原因,因为即使发生完全相同的情况,它们每次都不同。
编辑:在说值总是不同之后,事实证明这并不完全正确。如果我试图寻找到音频的最后,它总是会跳回到同一点(如果相信 getCurrentPosition() 方法的话,大约会提前 2-3 小时)。
为了让事情变得更复杂,如果我使用原始文件并使用 Audacity 和 LAME(使用默认设置)对其重新编码,这个问题就会消失。我只能这样做作为测试,因为当我的应用程序上线时,我将无法控制文件编码。
如果有人对此有任何想法,我们将不胜感激。
供参考:以下是Mac上afinfo命令获取的原始文件的值:
File: Test.mp3
File type ID: MPG3
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
no channel layout.
estimated duration: 35997.544490 sec
audio bytes: 216835607
audio packets: 1378031
bit rate: 48000 bits per second
packet size upper bound: 1052
maximum packet size: 522
audio data file offset: 1630
optimized
我重新编码的音频文件中的信息工作正常:
File: Test2.mp3
File type ID: MPG3
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
no channel layout.
estimated duration: 35997.596735 sec
audio bytes: 293659748
audio packets: 1378033
bit rate: 65000 bits per second
packet size upper bound: 1052
maximum packet size: 835
audio data file offset: 1560
optimized
audio 1587491712 valid frames + 576 priming + 1728 remainder = 1587494016
编辑:正在索尼 Xperia
上的 Android 6.0 上进行测试
我正在使用 android MediaPlayer 库播放一些 MP3 文件。我不负责这些文件,无论如何也无法更改它们,只能播放它们。
我目前更新了一个关于用户当前完成文件的进度条,将进度条的最大值设置为 mediaPlayer.getDuration()
。我知道这个返回的值是正确的。我每 500 毫秒 postDelayed 一个 Runnable,用 mediaPlayer.getCurrentPosition
的值更新进度条。这一切都按预期正常工作。
当我尝试使用 seekTo 方法时出现问题(但偶尔它会像我预期的那样工作)。我创建的媒体播放器对象注册了一个 OnSeekCompleteListener。当我调用 mediaPlayer.seekTo(50000)
时,使用 mediaPLayer.getCurrentPosition()
在 OnSeekCompleteListener 中输出的值是我告诉它要查找的正确值(在本例中为 51000,假设我们从 1000 毫秒开始进入文件)。但是,当 postDelayed runnable 运行以更新进度条时,mediaPlayer.getCurrentPosition()
返回的值通常(95% 的时间)远低于 OnSeekCompleteListener 中输出的值。
最终返回的值似乎没有任何韵律或原因,因为即使发生完全相同的情况,它们每次都不同。
编辑:在说值总是不同之后,事实证明这并不完全正确。如果我试图寻找到音频的最后,它总是会跳回到同一点(如果相信 getCurrentPosition() 方法的话,大约会提前 2-3 小时)。
为了让事情变得更复杂,如果我使用原始文件并使用 Audacity 和 LAME(使用默认设置)对其重新编码,这个问题就会消失。我只能这样做作为测试,因为当我的应用程序上线时,我将无法控制文件编码。
如果有人对此有任何想法,我们将不胜感激。
供参考:以下是Mac上afinfo命令获取的原始文件的值:
File: Test.mp3
File type ID: MPG3
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
no channel layout.
estimated duration: 35997.544490 sec
audio bytes: 216835607
audio packets: 1378031
bit rate: 48000 bits per second
packet size upper bound: 1052
maximum packet size: 522
audio data file offset: 1630
optimized
我重新编码的音频文件中的信息工作正常:
File: Test2.mp3
File type ID: MPG3
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
no channel layout.
estimated duration: 35997.596735 sec
audio bytes: 293659748
audio packets: 1378033
bit rate: 65000 bits per second
packet size upper bound: 1052
maximum packet size: 835
audio data file offset: 1560
optimized
audio 1587491712 valid frames + 576 priming + 1728 remainder = 1587494016
编辑:正在索尼 Xperia
上的 Android 6.0 上进行测试