Я использую библиотеку android MediaPlayer для воспроизведения некоторых файлов MP3. Я не отвечаю за эти файлы и в любом случае не могу их изменить, только играйте в них.Android MediaPlayer seekTo()/getDuration() не работает должным образом
В настоящее время я обновляю индикатор выполнения относительно того, насколько далеко находится файл, на котором находится пользователь, устанавливая максимальное значение индикатора выполнения на mediaPlayer.getDuration()
. Я знаю, что возвращаемое значение верное. I postDelayed Runnable каждые 500 мс, чтобы обновить индикатор выполнения со значением mediaPlayer.getCurrentPosition
. Все это работает правильно, как и ожидалось.
Проблема возникает, когда я пытаюсь использовать метод seekTo (однако очень редко он будет работать так, как я ожидаю). Объект медиаплеера, который я создал, имеет зарегистрированный на нем OnSeekCompleteListener. Когда я вызываю mediaPlayer.seekTo(50000)
, значение, которое выводится в OnSeekCompleteListener с использованием mediaPLayer.getCurrentPosition()
, является правильным значением, которое я сказал ему, чтобы искать (в этом случае 51000, предполагая, что мы начали с 1000 мс в файл). Однако, когда runnable postDelayed запускает обновление индикатора выполнения, значение, возвращаемое mediaPlayer.getCurrentPosition()
, обычно (95% времени) значительно ниже значения, которое выводилось в OnSeekCompleteListener.
Кажется, что нет никаких рифм или причин для значений, которые в конечном итоге возвращаются, поскольку они различны каждый раз, даже когда происходят одни и те же обстоятельства.
EDIT: После того, как мы сказали, что значения всегда разные, оказывается, что это не совсем так. Если я попытаюсь найти самый конец звука, он всегда будет возвращаться в ту же точку (примерно за 2-3 часа до того, как следует полагать метод getCurrentPosition()).
Чтобы усложнить ситуацию, если я возьму исходный файл и перекодирую его с помощью Audacity и LAME (с использованием настроек по умолчанию), эта проблема исчезнет. Я смог сделать это только как тест, так как когда мое приложение будет жить, я не буду контролировать кодирование файлов.
Если у кого-то есть идеи по этому поводу, они были бы весьма признательны.
Для справки: Ниже приведены значения исходного файла, полученного из afinfo команды на Mac:
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
Edit: Это испытывается на Android 6.0 на Sony Xperia
Я не уверен в этом, как описанные симптомы не совсем то же самое. Они не описывают правильное положение, о котором сообщается, а затем он впоследствии отскакивает назад. Кроме того, файлы кодируются с частотой 44100 МГц. Я наткнулся на них ранее и исключил их, поскольку они также были отмечены как устаревшие. – MultiJ
После некоторого дальнейшего исследования я протестировал эту проблему на Android 4.3, и на самом деле она представляет симптомы, описанные, по крайней мере, в одном из этих отчетов об ошибках. – MultiJ