just_audio icon indicating copy to clipboard operation
just_audio copied to clipboard

setFilePath returns null duration on Android

Open eddie-at-work opened this issue 4 years ago • 8 comments

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:

  1. Click "set the player"
  2. 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
  1. Notice the returned duration is null most of the time, the issue seems to be intermittent
  2. 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) Screenshot_1614645779

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 ¯_(ツ)_/¯

eddie-at-work avatar Mar 02 '21 00:03 eddie-at-work

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.

ryanheise avatar Mar 02 '21 02:03 ryanheise

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.

ryanheise avatar Mar 03 '21 02:03 ryanheise

👍 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

eddie-at-work avatar Mar 03 '21 17:03 eddie-at-work

Have you tried re-encoding your file?

ryanheise avatar Mar 09 '21 05:03 ryanheise

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:

  1. 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.
  2. Re-encode your audio file in a way that ExoPlayer is happy with.

ryanheise avatar Mar 14 '21 04:03 ryanheise

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 avatar Aug 23 '21 13:08 zhoffice

@zhoffice Have you considered trying my suggestion in my previous comment just above your comment?

ryanheise avatar Aug 23 '21 13:08 ryanheise

In this method "public void onPlaybackStateChanged(int playbackState)", even playbackState change to Player.STATE_READY, getDuration() method also return C.TIME_UNSET sometimes.

zhoffice avatar Aug 24 '21 07:08 zhoffice