React-native-track-player: playback-track-changed doesn't called for last track in IOS

Created on 7 Oct 2019  路  9Comments  路  Source: react-native-kit/react-native-track-player

The playback-track-changed event is ignored for last track in IOS.
Also it doesnt provide correct status in track change and it jumps one track.

iOS

Most helpful comment

This is also happening for me - when on iOS, the playback-track-changed listener isn't fired for the final track. Does anyone have any updates on this, or why it's happening?

All 9 comments

This is also happening for me - when on iOS, the playback-track-changed listener isn't fired for the final track. Does anyone have any updates on this, or why it's happening?

Yeah, still seems to be happening on iOS. I've found a workaround by using the eventListener for playback-state and checking for the playing state instead, since the playing state will always be fired between a track switch if it plays immediately. Then store the currentTrack in a state and compare against that to see if track has been switched or just playing the same track.

@HessiPard by this:

Also it doesnt provide correct status in track change and it jumps one track.

Did you mean that it reports the wrong values for track and nextTrack?

What I am seeing is:

  • track is set to the track that it changed TO (when the docs say it should be the track it changed FROM)
  • nextTrack is set to the track that will come after the one it changed to. (irrelevant, and clearly a bug in my mind, the docs say it should be the track it just changed TO)

Android behaves as the docs say.

Is this what you're seeing as well? Did you find a fix for it in the iOS native code?

Hi. Ive found the problem.
It is in events order: when playback changes track from previous to last it sends 2 events _.playUntilEnd_ and _.skippedToNext_ (see screenshot, Vendor/AudioPlayer/SwiftAudio/QueuedAudioPlayer.swift)
image
But for some reason ACTUAL event comes first is _.skippedToNext_ and then _.playUntilEnd_ (I suppose its some async issue)

But with the breakpoint in debug mode it goes in right order like it shoud

Ok, first, apologies to anyone who knows Swift and knows how to do this in a classier way. But I had two issues that seemed to be plaguing other people in iOS:

  • Multiple playback-queue-ended being dispatched. (One for the next-to-last track, one for the last track.)
  • playback-track-changed not being dispatched on the last track.

Adding a delay in the next method in QueuedAudioPlayer.swift fixed both for me. It seems that the logic in RNTrackPlayer was running after all the track information in the player had already moved on to the next track.

public func next() throws {
    event.playbackEnd.emit(data: .skippedToNext)
    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
        do {
            let nextItem = try self.queueManager.next()
            try self.load(item: nextItem, playWhenReady: true)
        } catch let error as NSError {
            print(error);
        }
    }
}

My solution was a bit different, but I think results in basically the same idea. Control the order of events.

https://github.com/curiousdustin/react-native-track-player/commit/1b8cfdb5c26ec4ce1dc0eca316ac8b8df1657e4f

Also, I believe portions of the issue have been resolved by: #772

@Guichaguri Even with #772, I believe there is still an issue of the track and nextTrack values being incorrect on iOS, because the events within SwiftAudio are NOT emitted synchronously. ( See here: https://github.com/curiousdustin/react-native-track-player/blob/v1.1.x-curious-no-submodule/ios/RNTrackPlayer/Vendor/AudioPlayer/SwiftAudio/Classes/Event.swift#L118)

@curiousdustin Nice! Are there any disadvantages of disabling automaticallyPlayNextSong and doing it manually? Can you open a PR with that?

@Guichaguri , as far as I can tell, disabling automaticallyPlayNextSong does not have any other side effects. This bool is only used in a single place in the SwiftAudio code, and my solution ends up calling the exact same code, only after we have been given the chance to send the proper events over the JS bridge.

https://github.com/jorgenhenrichsen/SwiftAudio/blob/master/SwiftAudio/Classes/QueuedAudioPlayer.swift#L188

https://github.com/curiousdustin/react-native-track-player/commit/1b8cfdb5c26ec4ce1dc0eca316ac8b8df1657e4f#diff-44c74236a1adc81d43903a61beab25eaR223

I will try to create a PR soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

toooldmohammad picture toooldmohammad  路  3Comments

JakeMotta picture JakeMotta  路  3Comments

moduval picture moduval  路  4Comments

mnlbox picture mnlbox  路  4Comments

sagargheewala picture sagargheewala  路  3Comments