just_audio icon indicating copy to clipboard operation
just_audio copied to clipboard

Allow preloading multiple positions

Open Palmik opened this issue 3 years ago • 7 comments

Amazing library!

Is your feature request related to a problem? Please describe. I want to allow users to skip to certain positions in a track and make sure it's as fast as possible. Therefore I want to be able to preload multiple positions ahead of time, such that seek to those positions will not need to buffer.

Describe the solution you'd like Add optional parameter Iterable<InitialSeekValues> to setAudioSource, to allow for loading multiple sections. Alternative solution would be to add Iterable<InitialSeekValues> as a param to load and allow calling load multiple times, even while the player is playing. The advantage here would be that the load of further sections of the track could be delayed.

Describe alternatives you've considered I could create a separate AudioSource and AudioPlayer for each position I want to preload and take advantage of initialPosition in setAudioSource. Then, when user seeks to that position, I would stop the old player and play the new one.

Palmik avatar Feb 01 '22 07:02 Palmik

Isn't it still there in setAudioSource?

ryanheise avatar Feb 01 '22 08:02 ryanheise

Yeah, I've considered that as an alternative. What I would like to be able to do is preload several positions in the same AudioSource and then be able to seek to those positions and have the playback start right away.

If I were to rely on setAudioSource, it would mean keeping a separate AudioPlayer for each position I want to preload, as far as I understand.

Cheers, P.

Palmik avatar Feb 01 '22 18:02 Palmik

What I mean is that no functionality was lost by that change. The old load method is exactly equivalent to the new setAudioSource(preload: true), so if you want the old behaviour, you can use that. If you want different behaviour, I think your feature description needs to be clarified.

ryanheise avatar Feb 02 '22 02:02 ryanheise

Thank you for helping me improve my understanding of the problem. I hope the new description is a bit clearer now.

Palmik avatar Feb 02 '22 06:02 Palmik

What you're requesting relates to buffering, but I have already exposed all of the native platform capabilities related to buffering which are passed into the constructor. If buffering configuration allows keeping a buffer once loaded, then you can achieve what you're trying to do by silently seeking to the set of positions you want to preload, one after the other. If the buffer is cleared once you seek away, this won't work. I think on iOS it will keep the buffer by default, but on Android it will clear the buffered regions that it deems aren't needed anymore.

ryanheise avatar Feb 02 '22 06:02 ryanheise

Let me clarify if I understand what you mean by "silently seeking":

player.setAudioSource(foo, preload: false);
await player.load();
await player.seek(extraPosition1);
await player.seek(extraPosition2);
await player.seek(Duration.zero);

// This should be buffered
await player.play();

// This might be buffered, depending on the platform:
await player.seek(extraPosition1);
await player.play();

Palmik avatar Feb 02 '22 06:02 Palmik

Yes that's what I mean, although "should be buffered" is going to depend on the platform's buffer behaviour.

ryanheise avatar Feb 02 '22 07:02 ryanheise