setFilePath returns null duration on Android
Which API doesn't behave as documented, and how does it misbehave? setFilePath() is supposed to return a Duration, but returns null most of the time
Minimal reproduction project https://github.com/eddie-at-work/just_audio_test
To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:
- Click "set the player"
- In the output text, you can see traces when:
- the bundled m4a asset (aac encoded) is written to the local app documents directory
- once written, we get instance of
File, which is used to call_player.setFilePath(_writtenFile.path) - outputs the duration value
- Notice the returned duration is null most of the time, the issue seems to be intermittent
- If you continue to click "set the player", it will occasionally work (returns the proper duration and starts playback)
Error messages Spotted these in the console
I/OMXClient(11211): IOmx service obtained
I/ACodec (11211): codec does not support config priority (err -2147483648)
Expected behavior The duration to be returned every time
Screenshots
Here's an example of the proper Duration returned and playback starting (if you persist in clicking "set the player", which tries to call setFilePath(_writtenFile.path) each time)

Desktop (please complete the following information):
- OS: Windows 10 Version 1909 OS Build 18363.1379
Smartphone (please complete the following information):
- Device: Android Simulator (Android version 10)
Flutter SDK version
[√] Flutter (Channel stable, 1.22.5, on Microsoft Windows [Version 10.0.18363.1379], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[!] Android Studio (version 3.6)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
[√] VS Code (version 1.53.2)
[√] Connected device (1 available)
Additional context
The sample file used is encoded on Android using flutter_audio_recorder, but there's a known issue where it doesn't actually encode in AAC on Android (https://github.com/rmbrone/flutter_audio_recorder/issues/9), so using a fork of that repo (https://github.com/hnvn/flutter_audio_recorder) to do so. The resulting file works on desktop media player, and it's properties say it's is, so ¯_(ツ)_/¯
One thing that it could be is that dart:io doesn't guarantee that a flush happens synchronously with the platform's notion of flush. You may need to (unfortunately) insert a delay between writing the file and passing it to the player.
I tested your m4a file by hosting it on a web server instead of a file, and got the same result. This indicates that it is either a problem with the encoding of the file, or it is a problem with ExoPlayer's decoders. It is more likely to be the former, given there is a history of similar problems with files generated by recorder plugins.
👍 thanks for looking into it, will test with different m4a's to check
ya, re: delay, FWIW I updated the repro project above to add a one second delay between the writing and the passing it to player, no luck https://user-images.githubusercontent.com/932757/109848382-70927e80-7c0d-11eb-8bd3-ca46892eae53.mp4
Have you tried re-encoding your file?
Any update on this? As mentioned above, it is either a problem upstream with Google's ExoPlayer or its a problem with the file itself. This suggests two alternative courses of action:
- File the bug with ExoPlayer and provide them with a link to your audio file so they can figure out whether it's actually a bug or whether your audio file is bad.
- Re-encode your audio file in a way that ExoPlayer is happy with.
I have same problem. Same amr file return null in first time, but return normal duration in next time, and return null in third time. It looks irregular.
@zhoffice Have you considered trying my suggestion in my previous comment just above your comment?
In this method "public void onPlaybackStateChanged(int playbackState)", even playbackState change to Player.STATE_READY, getDuration() method also return C.TIME_UNSET sometimes.