useAudioPlayer icon indicating copy to clipboard operation
useAudioPlayer copied to clipboard

Support for multiple audio sources

Open E-Kuerschner opened this issue 5 years ago • 10 comments

The Problem

Currently the library only supports one audio source being loaded at a time. If a user were to play a different sound the current sound object (the one currently playing) would need to be destroyed and a new instance created and loaded. This poses a problem for common interfaces like Spotify or any music library. A user will typically want to play their song the moment they click on a sound. If that sound has to initialize and load at the time they click it there could be some frustrating delay.

Possible Solution

There should be a way to register an audio source with the library and interact with it at a later time. For our audio library example, all the songs on screen could be loaded, then when the user clicks a song it may begin playing immediately.

Considerations

This library was created initially with the intention of only handling a single audio source out of simplicity. Is it the case that many applications have use cases for many audio sources within a single AudioContext?

E-Kuerschner avatar Jan 20 '20 16:01 E-Kuerschner

well, you know my vote :-)

rchrdnsh avatar Jan 21 '20 19:01 rchrdnsh

@rchrdnsh check out this branch I pushed up a commit to clean up the spotify-like example. Some of the functionality you described in your initial feature request was possible in the current version without any changes to the source code of the library. The key was to load the audio source with autoplay: true if nothing was already playing. Now you will get the behavior you desired when loading the page and clicking on a track.

E-Kuerschner avatar Jan 25 '20 22:01 E-Kuerschner

I still want to make a new release that allows multiple audio sources to be loaded at one time and played back later for performance on pages where multiple sounds might be played in sequence, but I just wanted to update you on one of the behaviors you mentioned.

E-Kuerschner avatar Jan 25 '20 22:01 E-Kuerschner

oh, that's awesome, thank you XD

rchrdnsh avatar Jan 27 '20 21:01 rchrdnsh

Just wanted to share my use case here: I have a bunch of tracks that I want to (lazy) load on the page, to quickly be able to listen to multiple versions of a track.

So the UI would look something like this: image

In terms of behaviour it would be best if each player kept its own state (ie. doesn't reset completely when a different track is played) but does pause when another is started.

Maybe this is already possible with the current design but it's not immediately clear to me what the best approach is. (current idea is to create a fully contained player per track + my own context to rule the "only play one at one time" logic)

Curious to hear your thoughts :)

GriffinSauce avatar May 22 '20 22:05 GriffinSauce

@GriffinSauce thanks for your input. I like your use case. When I originally built the lib I was trying to solve the problem of distributing responsibly across multiple components for controlling a single audio source. This is evident by the AudioPlayerProvider that must wrap the components using the hooks.

I have been playing around with the idea of a secondary api which would enable users to more casually create audio sources without the need for the centralized provider.

In the meantime, I think your idea would work. Create multiple AudioPlayerProvider nodes and manage the playing state across them yourself. It may be a little messy though since I don't think there is a direct way for the Providers to callback playback state to their parents without your own intervention

E-Kuerschner avatar May 23 '20 01:05 E-Kuerschner

Yeah that makes total sense, it's really well laid out in that sense!

This did it for me, just a simple useState context that wraps all the linked players:

 // Sync across players, only one is allowed to play at once
  const { playingFile, setPlayingFile } = useSongContext();
  useEffect(() => {
    if (playing) setPlayingFile(file);
  }, [playing]);
  useEffect(() => {
    if (playingFile && playingFile !== file) pause();
  }, [playingFile]);

GriffinSauce avatar May 23 '20 09:05 GriffinSauce

I would have used this package if it supported multiple audio sources.

But great work so far!

littlefinger42 avatar Feb 24 '21 16:02 littlefinger42

hi @littlefinger42 thanks for the comment!

Would you mind describing your use case a little bit?

E-Kuerschner avatar Feb 24 '21 16:02 E-Kuerschner

Great work! I just found this package today, and haven't played with it yet, but it looks very nice! Will try it out now!

I'm currently using react-audio-player, but when I found Howler I realized there is probably no better option than that :)

I need to provide quick transitions from one track to another in my application, and if accidentally going forward to next track it would be beneficial to go back and continue the previous from the position it was at.

I make an audio player as a side project for a very narrow and specific case, and actually plan to make it configurable in playlists that some tracks should autoplay when the previous is finished. Ideally they would then sound like one continuous track, (just like in the good old days, when live recordings were published on CD, and you could not hear when the new track started – I just tested a couple streaming services, and Tidal had a delay of several seconds, while Spotify had a shorter one, but still around a second (I didn't measure, though)).

I also need to make the application work offline, i.e. that user can download a set of audio files (a defined play list) while online, and then play them all while lacking internet connection. Should be fairly simple with service worker, I'm told.

aweibell avatar Jan 20 '22 20:01 aweibell

achieved in v2

E-Kuerschner avatar Jun 11 '23 19:06 E-Kuerschner