Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option (boolean) to auto advance to the next track #918

Closed
zacharywenner opened this issue Apr 28, 2020 · 19 comments
Closed

Add option (boolean) to auto advance to the next track #918

zacharywenner opened this issue Apr 28, 2020 · 19 comments
Assignees

Comments

@zacharywenner
Copy link

zacharywenner commented Apr 28, 2020

Is your feature request related to a problem? Please describe.
I'm unable to stop the track from auto-advancing to the next track. See Issue 917. I tried to stop the track from advancing with pause but it doesn't pause.

Describe the solution you'd like
Add a configuration option that lets you choose whether the track auto-advances to the next track or pauses after finishing. Right now the tracks all auto-advance if there is a next track.

Describe alternatives you've considered
Add the ability to pause in the event listener: Issue 917

Additional context
In our app, a user loads a playlist of tracks. They have a setting to choose whether the app should play the next track automatically or stop after each track. I would like to be able to update the Track Player config to reflect the user's choice of setting.

@curiousdustin
Copy link
Contributor

@Guichaguri is this an easy add on Android?

On iOS, SwiftAudio has a setting we can toggle.

However, looking briefly at Exoplayer, it seems ConcatenatingMediaSource doesn’t have an easy way to disable auto advancing. Which makes sense because seamless playback is the whole point.

Can we easily switch between media source types or something?

@Guichaguri
Copy link
Collaborator

It's doable, but not very precisely with the ConcatenatingMediaSource. Pausing in playback-track-changed should work on Android though.

@curiousdustin
Copy link
Contributor

I think I had tried that for some other reason and you end up getting blips of the next track 😞

@curiousdustin
Copy link
Contributor

I guess we should determine if this is necessary. Devs can always just not use the RNTP queue and do a single track at a time.

This can possibly cause issues when trying to change to the next track in the background though.

@Guichaguri
Copy link
Collaborator

Guess what?
It just became possible to make this work in ExoPlayer.
google/ExoPlayer#5660 (comment)

@curiousdustin
Copy link
Contributor

Nice!

So what approach do you think makes sense for exposing this in the TrackPlayer API?

Also, would we need a new playback event to know when the track is complete?

@Guichaguri
Copy link
Collaborator

I think we should still advance into the next track as expected, but set it to the paused state. playback-track-changed would still be triggered.

It would make sense to add a setter/getter for that, as setOptions is only related to metadata stuff and setupPlayer, which is related to the player, can not be updated dynamically.

@curiousdustin
Copy link
Contributor

hmm, I'll have to check, but I don't think this would match the default behavior on iOS by just disabling the auto play feature of SwiftAudio. On iOS I don't think it would go to the next track. But that may be easy to tweak.

@Guichaguri
Copy link
Collaborator

ExoPlayer doesn't advance either, so I don't know whether we should add a new event just for that or advance the track.

You can probably listen to playback-state, but that's not very intuitive either.

@curiousdustin
Copy link
Contributor

Maybe this would be related to other requests I have noticed regarding how to know when a track actually finished? A new event, such as playback-track-complete that only fires if it played to the end could maybe address those requests, and this one?

@Guichaguri
Copy link
Collaborator

Yeah, that should work

@infinitbility
Copy link

Maybe this would be related to other requests I have noticed regarding how to know when a track actually finished? A new event, such as playback-track-complete that only fires if it played to the end could maybe address those requests, and this one?

guys any update related to playback-track-complete

@andrekovac
Copy link

andrekovac commented Jun 7, 2020

This playback-track-complete value would be to mimic the behavior of the didJustFinish boolean in expo-av. Perhaps you can even call it similarly.

It would be important to add it since people moving here from expo-av (e.g. after ejecting an expo app - me for example 😉 ) are used to this functionality.

@zacharywenner
Copy link
Author

I also ejected from expo and was using the didJustFinish on expo-av which was helpful for our use. Now that logic is in "playback-track-changed" but it makes more sense to do on a "playback-track-complete". 

The 2 main things we would want on a track's finish:

  • Tracking progress: Marking a track "complete" for the user after it finishes.
  • Deciding whether to play the next track or stop after one when it finishes. This is resolved on Pause doesn't work in "PLAYBACK_TRACK_CHANGED" event #917 by pausing in playback-track-changed but it still goes to the next track.

@lizzieshipwreck
Copy link

Hey guys - so are you saying there is no way to stop this from auto-advancing on iOS? Like, if I have more than one track loaded it's not possible for me to prevent it from playing all the tracks in the queue?

Also, plus one for an 'onEnded' event. I kind of can't believe this library doesn't have this

@johkade
Copy link

johkade commented Mar 25, 2021

any updates on auto-play = false - behaviour?

@dcvz dcvz closed this as completed Aug 10, 2021
@edgargrs
Copy link

If someone is looking for a workaround. I'm doing the next:

useTrackPlayerEvents(events, async event => {
    const status = await TrackPlayer.getState();
    const position = await TrackPlayer.getPosition();
    const duration = await TrackPlayer.getDuration();
    if (event.type === TrackPlayerEvents.PLAYBACK_STATE) {
      if (
        status === TrackPlayer.STATE_BUFFERING &&
        duration > 0 &&
        Math.round(position) === Math.round(duration) &&
        shouldContinuePlaying // With this I can control if it should be continue playing, depends of the user actions
      ) {
        await TrackPlayer.pause();
        setIsPlaying(false); // Local state that controls play/pause icon
    }
  });

I hope it helps.

NOTE: I'm using "^1.2.7" version.

@ucheNkadiCode
Copy link

Thank you so much @edgargrs for your help on this

I was able to add this to my existing application like so. The TrackPlayers API has updated so this is for version 2.1.3. Make sure you are not trying to put this useTrackPlayerEvents function within a hook. I simply threw it under my useMemo in my main app screen.

useMemo(async () => {
// a bunch of set up app code
}, [])

const setupTrackPlayerEventListener = useTrackPlayerEvents(
  [Event.PlaybackState],
  async event => {
    const status = await TrackPlayer.getState()
    const position = await TrackPlayer.getPosition()
    const duration = await TrackPlayer.getDuration()
    console.log(`Uh oh! Some sound is playing!`)
    if (event.type === Event.PlaybackState) {
      if (
        status === TrackPlayerState.Buffering &&
        duration > 0 &&
        Math.round(position) === Math.round(duration)
        // && shouldContinuePlaying // With this I can control if it should be continue playing, depends of the user actions
      ) {
        console.log(`Soemthing `)
        await TrackPlayer.pause()
        // setIsPlaying(false); // Local state that controls play/pause icon
      }
    }
  }
)

@tsheaff
Copy link

tsheaff commented Dec 7, 2022

@dcvz Why did you close this? Is this feature implemented?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests