ryanheise / just_audio

Audio Player
1.03k stars 650 forks source link

Seek throws exception on big audio file on Android #679

Closed jcblancomartinez closed 2 years ago

jcblancomartinez commented 2 years ago

Which API doesn't behave as documented, and how does it misbehave? Seek API. When calling seek on big audio file on Android, it fails with ExoPlaybackException. Additionally, there is no way to catch the exception in Flutter code. I tried the following but 'Failed' doesn't get printed upon ExoPlaybackException.

_player.seek(duration).then( (value) => print('Succeeded'), onError: (dynamic error, StackTrace? stackTrace) => print('Failed'))

Minimal reproduction project Please, find here the modified repo.

To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:

  1. Click on play
  2. Click on the progress bar to jump to the position where 12:57 minutes of the audio are left.
  3. See error

Error messages

W/DefaultLoadControl( 5005): Target buffer size reached with less than 500ms of buffered media data.
W/DefaultLoadControl( 5005): Target buffer size reached with less than 500ms of buffered media data.
E/ExoPlayerImplInternal( 5005): Playback error
E/ExoPlayerImplInternal( 5005):   com.google.android.exoplayer2.ExoPlaybackException: Unexpected runtime error
E/ExoPlayerImplInternal( 5005):       at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:608)
E/ExoPlayerImplInternal( 5005):       at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal( 5005):       at android.os.Looper.loopOnce(Looper.java:201)
E/ExoPlayerImplInternal( 5005):       at android.os.Looper.loop(Looper.java:288)
E/ExoPlayerImplInternal( 5005):       at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal( 5005):   Caused by: java.lang.IllegalStateException: Playback stuck buffering and not loading
E/ExoPlayerImplInternal( 5005):       at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1046)
E/ExoPlayerImplInternal( 5005):       at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:482)
E/ExoPlayerImplInternal( 5005):       ... 4 more
I/CCodecConfig( 5005): query failed after returning 7 values (BAD_INDEX)
W/Codec2Client( 5005): query -- param skipped: index = 1342179345.
W/Codec2Client( 5005): query -- param skipped: index = 2415921170.
D/CCodecBufferChannel( 5005): [c2.android.mp3.decoder#290] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 5005): [c2.android.mp3.decoder#290] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 5005): [c2.android.mp3.decoder#290] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 5005): [c2.android.mp3.decoder#290] MediaCodec discarded an unknown buffer
I/hw-BpHwBinder( 5005): onLastStrongRef automatically unlinking death recipients
E/AudioPlayer( 5005): TYPE_UNEXPECTED: Playback stuck buffering and not loading
I/flutter ( 5005): A stream error occurred: PlatformException(2, Unexpected runtime error, null, null)

Expected behavior I would expect the audio to start playing in that position.

Screenshots After the exception is thrown, a spinner gets shown instead of the play button.

Screenshot1

Desktop (please complete the following information):

Smartphone (please complete the following information):

Flutter SDK version

[✓] Flutter (Channel stable, 2.10.3, on Ubuntu 20.04.3 LTS 5.13.0-35-generic,
    locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version
    32.0.0-rc1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

• No issues found!

Additional context

This issue happens with 1-hour long audio files too but it is easy to reproduce with this 12-hour long audio file.

Thanks.

jcblancomartinez commented 2 years ago

Hi @ryanheise ,

Thanks for your work on this plugin.

This is the only issue preventing me from onboarding this plugin.

Could you please let me know if this would be an easy fix?

Thanks.

Best regards.

ryanheise commented 2 years ago

Additionally, there is no way to catch the exception in Flutter code.

Your log shows "a stream error occurred" which indicates that it is being caught by Flutter.

If the error is still an issue for you, you may need to report it upstream with Google's exoplayer since that appears to be the actual behaviour of exoplayer. They may also be able to advise you on alternative audio encodings you can try since seeking behaviour is dependent on the encoding.

ryanheise commented 2 years ago

I notice that your example is based on MP3, and it is worth noting that that format is not suitable for seeking in general and especially for very long audio.

jcblancomartinez commented 2 years ago

How would you catch the exception to show an error message and replace spinner with play button?

Thanks.

ryanheise commented 2 years ago

In terms of how to catch the exception, you already did that in your example which is what I pointed out in my first comment with your "A stream error occurred" printout. I would have thought it's a simple matter of replacing that one line of code that prints "A stream error occurred" with your own code to display whatever it is you want to display.

In any case this bug report is related to the seek behaviour, and I would say that catching the error doesn't actually solve the problem. To solve the problem, I suggest you look at the way upstream ExoPlayer behaves with long mp3 files and consider using a different encoding.

jcblancomartinez commented 2 years ago

Regarding catching the error, sorry for the confusion brought.

You are right, the exception is being caught and printed here.

Thanks.

jcblancomartinez commented 2 years ago

The following configuration solved my issue:

AudioPlayer( audioLoadConfiguration: AudioLoadConfiguration( androidLoadControl: AndroidLoadControl( prioritizeTimeOverSizeThresholds: true )))

Thanks.

github-actions[bot] commented 2 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with just_audio.