Just_audio: ConcatenatingAudioSource with lots of children takes a very long time to load

Created on 1 Feb 2021  Â·  6Comments  Â·  Source: ryanheise/just_audio


Which API doesn't behave as documented, and how does it misbehave?

Creating a ConcatenatingAudioSource with lots (~1000) of children takes a very long time (>20 seconds).

In my application, users can have playlists with an arbitrary number of items.

Minimal reproduction project

To Reproduce (i.e. user steps, not code)

final player = AudioPlayer();
final songs = /// 1000+ sources
await player.setAudioSource(
  ConcatenatingAudioSource(children: songs),
);

Error messages

Expected behavior

I'd expect to be able to set the audio source and start playing the first source within a couple seconds, even with a large number of sources (since only the initial few sources are actually being fetched).

Screenshots

Desktop (please complete the following information):

  • OS: MacOS

Smartphone (please complete the following information):

  • Device: iPhone 12 Pro Max Simulator

Flutter SDK version

[✓] Flutter (Channel beta, 1.25.0-8.3.pre, on Mac OS X 10.15.7 19H114 darwin-x64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.52.1)
[✓] Connected device (2 available)

• No issues found!

Additional context

2 fixing bug

Most helpful comment

This issue affects both iOS and macOS. I have a reproduction case on #206 which has helped me to reproduce this issue.

The solution is to rewrite the enqueueFrom method so that it enqueues only the next few items, and whenever the player advances to the next item, we should add another item onto the end. This behaviour should be the default, but it should also be tied to the ConcatenatingAudioSource.useLazyPreparation option.

This is a tricky area of the code to work on since it can easily break things, but it is an important feature to add, and as long as it undergoes sufficient testing, it should be worth doing.

I've marked this issue as "fixing" which means it is on my priority list. That said, there are some other things that were already on my priority list, such as the visualizer, and the null-safe release of audio_service (which will be based on the one-isolate model).

All 6 comments

Hi @smkhalsa unfortunately I will need you to fill in the sections as instructed. In the section called "User steps, not code", you actually copied and pasted code. This should be in the previous section "Minimal reproduction project" which you have left empty, but which should contain a link to a git repository that I can clone and test.

This issue affects both iOS and macOS. I have a reproduction case on #206 which has helped me to reproduce this issue.

The solution is to rewrite the enqueueFrom method so that it enqueues only the next few items, and whenever the player advances to the next item, we should add another item onto the end. This behaviour should be the default, but it should also be tied to the ConcatenatingAudioSource.useLazyPreparation option.

This is a tricky area of the code to work on since it can easily break things, but it is an important feature to add, and as long as it undergoes sufficient testing, it should be worth doing.

I've marked this issue as "fixing" which means it is on my priority list. That said, there are some other things that were already on my priority list, such as the visualizer, and the null-safe release of audio_service (which will be based on the one-isolate model).

@ryanheise The enqueFrom you are talking about is here? So that's not something we could handle on plugin user side, right?

I was noticing similar behavior with 43 items in the playlist. My UI freezes while they are loading on macOS and iOS. On the iOS simulator the freeze lasted 30 seconds. Web and Android are fine.

Can you think of any temporary workarounds I could pursue on my side?

That's correct. The solution involves improving the enqueueFrom so that it can enqueue just a few items ahead instead of the whole list, when the useLazyPreparation option is set to true. That involves modifying the Objective C code in the plugin.

As for a workaround, I can think of 2 things to try:

  1. The easiest thing to try (although I don't know whether it will have any effect) is to play with the new buffering options available in the dev branch, which you can pass into the constructor of AudioPlayer. With these options (in particular preferredForwardBufferDuration), you may be able to limit the size of the forward buffer and thus reduce the time spent loading. The problem with this is that iOS isn't guaranteed to follow your preferred buffer parameters, and even if it did, it still may need to load a little bit of each track.
  2. Forego just_audio's playlist management and implement the lazy loading within your own app. So let's say you have a list of 43 items, you could create a ConcatenatingAudioSource with just the first 3 items in it. Then when playback approaches the 3rd item, you can dynamically insert more items onto the end of it. The drawback is that you can't simply use just_audio's state to tell you what's in your entire playlist, because it'll only know about the sublist of items you've added, so you'll need to maintain your own full playlist state outside of just_audio.

I forgot about the possibility of adding items to an existing playlist. That's a good idea. Thank you!

Just to add onto this, I have only noticed this issue on MacOS release/debug and only on iOS Simulator. This issue is not present, at least for me, on Physical iOS device whether release or debug. Android is Fine.
I am adding 100 tracks at once.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ReaganRealones picture ReaganRealones  Â·  9Comments

ryanheise picture ryanheise  Â·  7Comments

ryanheise picture ryanheise  Â·  13Comments

mohammadne picture mohammadne  Â·  6Comments

lain-ke picture lain-ke  Â·  4Comments