react-native-track-player icon indicating copy to clipboard operation
react-native-track-player copied to clipboard

Previous track can be played while the current track is initially loading

Open jspizziri opened this issue 3 years ago • 10 comments

Describe the Bug From https://discord.com/channels/567636850513018880/600714011318681610/974596964912070666

In iOS if any track of the queue has wrong track url (like no track found) then track change action does change the current track info and payback track change event also trigger. But previously playing track still continue to play.. actual track does not change..

Steps To Reproduce

Code To Reproduce

Environment Info:

jspizziri avatar May 13 '22 10:05 jspizziri

This problem occurs in ios, It's ok in android.

If there is wrong url of any tracks then playback track changed event fire and queue change but still previous track continue to play. it does not change even after playback-error event fired. Track should change at the time of playback track change event fire.

Steps To Reproduce Enter few tracks in queue having wrong/invalid url. use TrackPlayer.skip function to change track. Observe the behavior. some possible error events after console log, {error: 'The requested URL was not found on this server.', type: 'playback-error'}, {error: 'Could not connect to the server.', type: 'playback-error'}, {error: 'A server with the specified hostname could not be found.', type: 'playback-error'}

Code To Reproduce It can be reproducible in the given example code.

System Information are: OS: macOS 11.6.2 CPU: (4) x64 Intel(R) Core(TM) i5-5350U CPU @ 1.80GHz Memory: 27.64 MB / 8.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.13.1 - /usr/local/bin/node Yarn: 1.22.18 - ~/Documents/ashraful/musiczi-mobile/node_modules/.bin/yarn npm: 8.1.2 - /usr/local/bin/npm Watchman: 2021.12.13.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 Android SDK: System Images: android-30 | Google Play Intel x86 Atom_64 Android NDK: Not Found IDEs: Android Studio: Not Found Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild Languages: Java: 17.0.1 - /usr/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.13.1 => 16.13.1 react-native: 0.63.4 => 0.63.4 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

react-native-track-player version 2.2.0-rc3 also reproducible in 2.1.3 and 1.2.7 I found this issue in simulator. Could not test in real device.

AshrafulAfruz avatar May 17 '22 10:05 AshrafulAfruz

@AshrafulAfruz I tested this against the work that's been done on this PR (which addresses a bunch of track changed issues), and I wasn't able to reproduce it. For that reason, I'm going to consider this effectively a "duplicate" issue of the issues that were identified there and close it.

If you can, please pull down my branch and verify that it's fixed from your perspective too. If not, I'm happy to reopen.

jspizziri avatar May 17 '22 18:05 jspizziri

https://user-images.githubusercontent.com/38793029/170449168-cac43c92-3a8e-4ad1-83f3-757bd49c7bc8.mp4

@jspizziri I don't know how could I test by your changes. What I did was cloning your repository and run example project from there. But I think it's using version 2.2.0-rc3. Here i'm providing a screencast ( on example project showing it's behavior) so that it might help. I used given track's array with adding one track object of my own. Please can you check if your changes actually address this issue.?

AshrafulAfruz avatar May 26 '22 08:05 AshrafulAfruz

@AshrafulAfruz When you cloned my fork did you make sure to checkout my branch? You need to test against the fix/ios-track-changed branch.

jspizziri avatar May 26 '22 12:05 jspizziri

@jspizziri I have tested in your branch. The problem still exists. But your new refactored example code bypasses that scenario as it remain in connecting state. If there is errored track it remain in connecting state but invoking trackplayer.play() at that time causes the last correct track to start playing (though playback progress show current track index).

AshrafulAfruz avatar May 30 '22 08:05 AshrafulAfruz

@AshrafulAfruz Can you share a reproducible example based off of my branch? Please also include steps to reproduce. I can't reproduce it so we must be missing each other on some point.

jspizziri avatar May 30 '22 14:05 jspizziri

@jspizziri For reproducing the problem I have made following changes,

In file example/src/components/PlayPauseButton.tsx changed

if (isLoading) {
    return (
      <View style={styles.statusContainer}>
        {isLoading && <ActivityIndicator />}
      </View>
    );
  }

to

if (isLoading) {
    return (
      <>
        <Button
          title={isPlaying ? 'Pause' : 'Play'}
          onPress={onTogglePlayback}
          type="primary"
        />
        <View style={styles.statusContainer}>
          {isLoading && <ActivityIndicator />}
        </View>
      </>
    );
  }

so that play button can show at state connecting time.

And modified example/src/assets/data/playlist.json as follow

[
  {
    "url": "https://react-native-track-player.js.org/example/Longing.mp3",
    "title": "Longing",
    "artist": "David Chavez",
    "artwork": "https://react-native-track-player.js.org/example/Longing.jpeg",
    "duration": 143
  },
  {
    "url": "https://react-native-track-player.js.org/example/Soul%20Searching.mp3",
    "title": "Soul Searching (Demo)",
    "artist": "David Chavez",
    "artwork": "https://react-native-track-player.js.org/example/Soul%20Searching.jpeg",
    "duration": 77
  },
  {
    "url": "http://184.154.202.243:8028/stream",
    "title": "Radio Amar",
    "artwork": "https://d2h2ofqh3tbq9r.cloudfront.net/station_image/logo_2.png",
  },
  {
    "url": "http://google.com",
    "title": "Google",
    "artwork": "https://react-native-track-player.js.org/example/Soul%20Searching.jpeg",
  },
  {
    "url": "https://react-native-track-player.js.org/example/Lullaby%20(Demo).mp3",
    "title": "Lullaby (Demo)",
    "artist": "David Chavez",
    "artwork": "https://react-native-track-player.js.org/example/Lullaby%20(Demo).jpeg",
    "duration": 71
  },
  {
    "url": "https://react-native-track-player.js.org/example/Rhythm%20City%20(Demo).mp3",
    "title": "Rhythm City (Demo)",
    "artist": "David Chavez",
    "artwork": "https://react-native-track-player.js.org/example/Rhythm%20City%20(Demo).jpeg",
    "duration": 106
  }
]

Adding invalid track in 3rd and 4th position.

Reproducible steps:

  1. run the app after modifying above 2 files.
  2. play first/second track
  3. click next (Observe in 3rd track it continue to loading state.)
  4. click on the play button. (Previously running track start to resume). Also observe the log.

Optional extra steps: 5) toggle between play pause. (observe the behavior) 6) click next. (it will exibit the same behavior of from 3rd step for 4th track also.

Expected behavior:

When track change event fire it should change previously played track immediately.

Let me know if you could reproduce this problem.

AshrafulAfruz avatar May 31 '22 06:05 AshrafulAfruz

@AshrafulAfruz alright. I've followed your steps and I can reproduce your behavior.

In this scenario it is correct that the track-changed is fired, as the app has transitioned to the next track, but because it's broken it sits there in a loading state and eventually fails with the following exception:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error when sending event: playback-error with body: {
    error = "The request timed out.";
}

The only issues I see here are the following:

  1. It is strange that if you hit the "play" button again it will briefly play the previous track (which is perhaps your initial report). I agree that this shouldn't happen, but I do think it's fairly edge-case, as a good design pattern would be to not allow users to hit the play button when a track is attempting to load. Regardless, I do think it's a bug, and I think the expected behavior would effectively for play to do nothing in this scenario. I'm going to reopen this issue.
  2. A request timeout error should not be causing a fatal exception and should instead be bubbling up through the PlaybackError event. This I think can be considered a separate issue, and I'm opening a new ticket for it.

jspizziri avatar Jun 01 '22 20:06 jspizziri

@jspizziri Running previous track is a problem when programmatically control the playing of track. It limits the functionality. For example, one of my requirements is that when hitting next button, track should start playing irrespective of currently it was playing or not. So what i do is after skipping to the next track manually start the playback.

AshrafulAfruz avatar Jun 05 '22 05:06 AshrafulAfruz

@jspizziri I've just found that android also have problem regarding errored tracks. Now in android playback error is not fired and playback state become 0 (State.none) and further operation can not be performed. like changing to a good track then trackplayer.play() does not change the state anymore.

AshrafulAfruz avatar Jun 08 '22 08:06 AshrafulAfruz

Looking at the source code I can see the fail case for the initial load of the item happening here:

https://github.com/doublesymmetry/SwiftAudioEx/blob/main/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapper.swift#L228

But indeed, nothing is done to the current item at this point – which means it just continues playing. We probably want to call AVPlayerWrapper.reset(true) at that point, which will replace the current avplayer item with nil, causing it to stop loading & playing:

https://github.com/doublesymmetry/SwiftAudioEx/blob/main/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapper.swift#L255

puckey avatar Sep 01 '22 19:09 puckey

Opened a pull request to solve this here: https://github.com/doublesymmetry/SwiftAudioEx/pull/25

puckey avatar Sep 01 '22 19:09 puckey

This issue will be fixed when v3.2 is released.

jspizziri avatar Sep 20 '22 14:09 jspizziri