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

First track Audio file is fetched and played momentarily when multiple tracks add()ed #1781

Closed
bradfloodx opened this issue Oct 7, 2022 · 25 comments
Labels
Bug Platform: iOS Unconfirmed Bugs that have not been confirmed by the core team.

Comments

@bradfloodx
Copy link
Collaborator

Describe the Bug
CONTEXT: In our App (using RNTP), a User can browse a Playlist and tap on any Song in that Playlist to begin playing the Song (from that position in the Playlist). In our code when a User taps Play on a Song we first reset() the player, then we add() all the Songs from the Playlist into the Queue, then we skip(index) to the Index of the Song they have chosen (eg they might want to start at Song 3 of 10), then we play().

We found a bug on iOS where some users were hearing a momentary playback of the first Song in the Queue, BEFORE the skip(index) and play() had been called.

Upon further investigation, by monitoring my local file server, I can see that when adding Tracks into the Queue, there is a network request to fetch the first track in the queue, and then it is momentarily played audibly, even before the play() method is triggered.

Steps To Reproduce
Note: This appears to only happen on faster/newer devices. Reproduced on a physical iPhone 13 Pro running iOS 16, and on the simulator.

  1. Add multiple tracks to queue
  2. Observe network request to first track's audio file

Code To Reproduce

await TrackPlayer.add([validDemoTrack1, validDemoTrack2]);

Observe HTTP logs..

[2022-10-06T10:27:57.911Z] 10.0.0.90 "GET /demo-story.mp3" "AppleCoreMedia/1.0.0.19F70 (iPhone; U; CPU OS 15_5 like Mac OS X; en_us)"
[2022-10-06T10:27:57.915Z] 10.0.0.90 "GET /demo-story.mp3" "AppleCoreMedia/1.0.0.19F70 (iPhone; U; CPU OS 15_5 like Mac OS X; en_us)"
[2022-10-06T10:27:57.926Z] 10.0.0.90 "GET /demo-story.mp3" "AppleCoreMedia/1.0.0.19F70 (iPhone; U; CPU OS 15_5 like Mac OS X; en_us)"

Replicable on Example App?
Can you replicate this bug in the React Native Track Player Example App?
Yes.

Environment Info:

  • main branch of react-native-track-player as of today.
  • iOS - device and simulator

How I can Help
I'm wondering if this "fetch" and short "play" is triggered by the resolveImportedPath() method in add() being called here https://github.com/doublesymmetry/react-native-track-player/blob/main/src/trackPlayer.ts#L97 (which also explains why the first artwork is fetched too). However, looking at that code I would expect a request for all tracks, because that code loops through them all, but I only ever see a network request for the First track (during the add() step).

Regardless, there should not be any audio played until play() is fired, so there seems to be an issue somewhere.

Thoughts?

@bradfloodx bradfloodx added the Bug label Oct 7, 2022
@jspizziri jspizziri added the Unconfirmed Bugs that have not been confirmed by the core team. label Oct 17, 2022
@DennisdeWitNL
Copy link

Yes, I have the same issue. When skipping to a next live stream, I can hear the previous livestream for a second. Also, it seems TrackPlayer.play(); is first resuming the previous track and then skips and plays the next track. This is the behavior you mentioned, right?

@sonorus-eric
Copy link

Yes

I have the same problem,if only use skip can work just the pre stream playing state

@paulosabayomi
Copy link

I am facing the same issue, has anyone found a solution for it?

@bradfloodx
Copy link
Collaborator Author

My workaround is adding the upcoming tracks, and then adding the previous tracks afterwards. Like so...

const currentTrackOnwards = tracksToAdd.slice(skipToIndex);
const earlierTracks = tracksToAdd.slice(0, skipToIndex);
await TrackPlayer.add(currentTrackOnwards);
await TrackPlayer.play();
await TrackPlayer.add(earlierTracks, 0); // Insert "previous" tracks in front of index 0

@paulosabayomi
Copy link

@bradleyflood the approach is good, but that would not make the songs play as they appear on the UI,

if the library plays the next song automatically it would not be the next song to the last played song on the UI

if this issue is not fixed, I might be forced to write my own library for RN audio from scratch 😃

@bradfloodx
Copy link
Collaborator Author

bradfloodx commented Nov 23, 2022

@Amusa-Paulos My workaround plays exactly as shown in the UI, that's the whole point of it :)

@paulosabayomi
Copy link

okay @bradleyflood I will give it a try

@wreyw213
Copy link

wreyw213 commented Jan 11, 2023

another workaround could be to reset player and add all items and skip to that index

let list  /* List of Audio File in this format [{
                            "artwork": ,
                            "id":
                            "title": ,
                            "url": 
                            "artist":
                        }]*/
                        
                 await TrackPlayer.pause()
                 await TrackPlayer.seekTo(0) //just in case
                 await TrackPlayer.reset()
                   
                        await TrackPlayer.add(list)
                        await TrackPlayer.skip(skipToIndex)
                        await TrackPlayer.play()

@PiotrWszolek
Copy link

PiotrWszolek commented Jan 20, 2023

I experienced the same while trying to play one song out of queue, here is my solution maybe it will help you:

const playTrackOutOfQueue = async (track: Track) => {
    queue = await TrackPlayer.getQueue();
    await TrackPlayer.reset();
    await TrackPlayer.add(track);
    await TrackPlayer.play();
  };

  const restoreQueue = async () => {
    if (queue) {
      await TrackPlayer.pause();
      await TrackPlayer.reset();
      await TrackPlayer.add(queue);
      queue = null;
    }
  };

@mitchdowney
Copy link
Contributor

mitchdowney commented Jan 22, 2023

@puckey any chance that your #1713 PR addresses this iOS bug? I ask because I see:

Implement TrackPlayer.load(track): replaces the current track with the supplied track or creates a track when the queue is empty. This feature would mainly be used by simple single track apps – for example a radio station app

in your PR, which makes me wonder if TrackPlayer.load would handle playing a new track better than using TrackPlayer.add followed by TrackPlayer.skipToNext.

I see some people are using reset to work around the issue, but I really don't want to do that because I think it triggers playback-track-changed and playback-queue-ended which could lead to unintended weird race conditions before loading the correct new track.

UPDATE: hmm, I wonder if you're describing the root of the issue here: doublesymmetry/SwiftAudioEx#14 (comment)

@ninacoder-info
Copy link

Hi, please somebody can look in to this issue? it was there from 2022 Oct :(

@tjkyner
Copy link

tjkyner commented Jan 26, 2023

@bradleyflood thanks for sharing your workaround!

Were you able to figure out why adding a track to the queue results in multiple network requests? I've been running into an issue where playing a track is delayed by 1-3 seconds because TrackPlayer.add() seems to hit the supplied url up to four times and doesn't start playing until the final response.

@bradfloodx
Copy link
Collaborator Author

Hey @tjkyner nah I never got to the bottom of it. But it sounds like work by Puckey and others will fix it in upcoming versions.

@bradfloodx
Copy link
Collaborator Author

Hi @ninacoder-info you could look into it ;) We are all just as busy. Cheers :)

@puckey
Copy link
Collaborator

puckey commented Feb 22, 2023

@bradleyflood could you verify if this issue has been fixed in nightly?

@bradfloodx
Copy link
Collaborator Author

Yo :) Tried reverting my code to test this today, but couldn't simulate it! hah. I think it only happens in TestFlight and Production versions. So I'll test it in an upcoming TestFlight build.

@jspizziri
Copy link
Collaborator

@bradleyflood are you ok if we consider this resolved?

Additionally for anyone else looking to bypass RNTP's native Queue/Playlist functionality please use the newly introduced load(track) method.

@bradfloodx
Copy link
Collaborator Author

@jspizziri happy to close if this is confirmed fixed. I haven't got capacity at the moment to test it sorry.

@ianniu
Copy link

ianniu commented Mar 8, 2023

In my scenario, when I add a new track and skip to it, or when I skip forward/backward and play, the track player will first play for some seconds then skip and play the right song. If anyone doesn't want to use reset() as a workaround to avoid the race condition, here's my solution:

import { selectLoadChangeTrack, setLoadChangeTrack } from '../../store/slices/playerSlice'

const loadChangeTrack = useSelector(selectLoadChangeTrack)

// skip to a new track will cause playerState change, so we can use useEffect to check when it change to State.Ready and then call play()
useEffect(() => {
  const checkReadyAndPlay = async () => {
    if (!loadChangeTrack) return

    if (playerState === State.Ready) {
      await TrackPlayer.play()
      dispatch(setLoadChangeTrack(false))
    }
  }
  checkReadyAndPlay()
}, [loadChangeTrack, playerState])

const onPressSkipForward = async () => {
  ...
  await TrackPlayer.pause()
  await TrackPlayer.seekTo(0)
  await TrackPlayer.skipToNext()
  dispatch(setLoadChangeTrack(true))
  ...
}

@bradfloodx
Copy link
Collaborator Author

@ianniu does this still happen for you in the nightly release of react-native-track-player?

@ianniu
Copy link

ianniu commented Mar 8, 2023

@ianniu does this still happen for you in the nightly release of react-native-track-player?

I haven't upgraded it. I'm using 3.2.

@bradfloodx
Copy link
Collaborator Author

@ianniu are you able to try the nightly and see if this issue is fixed?

@ianniu
Copy link

ianniu commented Mar 8, 2023

@ianniu are you able to try the nightly and see if this issue is fixed?

Sorry, I'm not able to do that for now.

@mitchdowney
Copy link
Contributor

mitchdowney commented Mar 8, 2023

@bradleyflood @ianniu as far as I have been able to tell, the issue no longer happens for me with the nightly branch. I no longer hear the first episode in the queue play briefly after an episode later in the queue begins to play.

So I think it is fixed, but I also made this patch change around the same time (add iosInitialTime handling) and I'm not sure if that overlaps with the issue. https://github.com/podverse/podverse-rn/blob/develop/patches/react-native-track-player%2B3.2.0-bb749e5d286737681ba8907dfd287480eb1cec45.patch#L5389

@puckey
Copy link
Collaborator

puckey commented Mar 16, 2023

Considering this fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Platform: iOS Unconfirmed Bugs that have not been confirmed by the core team.
Projects
Development

No branches or pull requests