2

Question: How do I know whether or not the action of fetching the audio from a remote source (e.g. loading a player with player.setUrl(url1, preload: true)), has already been done for this player?

    AudioPlayer player = AudioPlayer();
     
    // Desired:
    // `true` if the `load()` action has been completed and that audio is currently 
    // `loaded` in the player (i.e. it is not necessary to fetch that audio again 
    // in order to play it)
    bool loaded = player.hasAudio; // false 

    // Once this is awaited, the player now has an audio `loaded`  
    await player.setUrl(url1, preload: true); 

    loaded = player.hasAudio; // true

In other words, what I don't want is calling player.setUrl(url1, preload: true) twice in a row, fetching the data twice.

I am looking for the property that is equivalent to player.hasAudio in my example above. Or another way to get a similar result.

lenz
  • 2,193
  • 17
  • 31
  • 1
    Based on the state machine from the [doc](https://pub.dev/packages/just_audio) I'm tempted to think that this might do the trick: `bool loaded = player.processingState == ProcessingState.ready || player.processingState == ProcessingState.completed;`. Any feedback is appreciated. – lenz Jun 25 '21 at 07:14

1 Answers1

3

Ok so based on the docs I can extrapolate this for my use case:

// `true` if the `load()` action has been completed and an audio is currently 
// `loaded` in the player
bool loaded = player.processingState == ProcessingState.ready ||
 player.processingState == ProcessingState.completed ||  
 player.processingState == ProcessingState.buffering;

// Or with less code but probably less intuitive
bool loaded = player.processingState.index > ProcessingState.loading.index;


loaded is true if player has been previously loaded and:

  • playback is over :player.playing == true && ProcessingState.completed
  • playback hasn't started: player.playing == true && player.processingState == ProcessingState.ready
  • playback is in progress: player.playing == true && player.processingState == ProcessingState.ready
  • playback has been paused:player.playing == false && player.processingState == ProcessingState.ready
  • playback is resumed from paused state (triggers multiple state changes)
    1. player.playing == true && player.processingState == ProcessingState.ready
    2. then player.playing == true && player.processingState == ProcessingState.buffering
    3. then player.playing == true && player.processingState == ProcessingState.ready

From the docs:

It is important to understand that even when playing == true, no sound will actually be audible unless processingState == ready which indicates that the buffers are filled and ready to play.


As for the currently loaded AudioSource, I haven't yet found a way to expose the currently loaded AudioSource's data...

lenz
  • 2,193
  • 17
  • 31
  • 1
    While there is no getter for the current audio source as set by `player.setAudioSource`, you can get the current indexed audio source by looking at `player.sequence![player.currentIndex!]`, assuming they're not null (otherwise check first). – Ryan Heise Jun 26 '21 at 01:40
  • Thank you @RyanHeise, I'll check it out. Thanks for your great work on this package! – lenz Jun 26 '21 at 09:03