3

My use case is that I have an mp3 file playing in the background that uses audio_service and just_audio packages in flutter. Let's say the file is 'A'.

My app lets 'A' download from url to local file while playing 'A' from url (a separate background task).

Series of steps:

  • just_audio plays 'A' from url (for ex. https://something/A.mp3)
  • 'A' is downloaded from url to my file (file:///something/A.mp3)
  • 'A' is still playing in the background.
  • as the 'A' is downloaded, I want to change the audio source of the player from http uri to file uri.

As I am using a queue, I use concatenatingAudioSource to set the source of the player.

I tried to remove old uri and add the new uri and bring back the state before changing the uri. (as below)

bool isPlaying = _player.playing;
Duration position = _player.position;
int index = params['index'];
bool isCurrentItem = _player.currentIndex == index;
await concatenatingAudioSource.removeAt(index);
await concatenatingAudioSource.insert(
    index, AudioSource.uri(Uri.parse(params['uri'])));
updateUriInQueue();

// broadcast the queue
await AudioServiceBackground.setQueue(queue);

// Note: a small break might occur when changing the state

// return to it's original state after changing uri
if (!isCurrentItem) return;
await _player.seek(position, index: index);
if (isPlaying) _player.play();

For a side-note, I don't use the mediaItem.id as a URI and have it stored inside mediaItem.extras.

From the above code, it clearly is seen that the player stops and plays after the uri is changed. I would like to know if there is a smoother way to change the player uri without disturbing the output.

immadisairaj
  • 608
  • 4
  • 11
  • It seems like what you really want is `LockCachingAudioSource` or your own custom subclass that does something similar. – Ryan Heise Jun 19 '21 at 04:35
  • That is something new for me. After going through it, I find it that it caches the file internally to a specific location. It really is a wonderful thing. But, my use case is a bit different, when I download the file, it is being downloaded to external storage (I am using a different pluggin). The download is an optional for the user. So, I would like to keep the download plugin and change the audio source to the file path as it runs.. – immadisairaj Jun 19 '21 at 05:57
  • Hence your own custom subclass (of `StreamAudioSource`). For a smooth transfer, you need to feed a continuous stream of audio to the player, and you can build your logic into that subclass to switch over at a certain byte position when you're ready to switch to the file. You can also use the implementation of `LockCachingAudioSource` as a guide for your own implementation. – Ryan Heise Jun 19 '21 at 06:05
  • Thanks for telling me about this. As the file is being cached and doesn't interrupt the audio. I thought of using it instead of making a complete new one (I want to stay with what is currently in the pluggin). So, I made a workaround in a way that the source updates dynamically when it finishes playing (currently working). I am using `LockCachingAudioSource(link, filePath: )` when the file is downloaded. I know it's not the right way to do (having fileuri in place of link doesn't work). Also, I am not able to add AudioSource.uri and LockCaching in same concatenation. – immadisairaj Jun 19 '21 at 11:43
  • When I modify the example by changing one item in the concatenation to a lock caching audio source, it works fine, so I'm not sure what the issue would be in your case. – Ryan Heise Jun 22 '21 at 16:15
  • Thanks for the comment. I'll try it out with the new release of just_audio and get back. The issue before was while initialising with lock caching (as first source) works fine. But, when I first try to initiate with audio source (as first source) I am not able to append lock caching source. Anyway I'll try to figure out and get back if I still face issue. – immadisairaj Jun 23 '21 at 01:21

0 Answers0