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

Track player sets itself to paused after buffering

Open colinricardo opened this issue 3 years ago • 9 comments

Describe the bug Not sure if I'm doing something wrong, but I'm seeing these events when I do a simple addTrack + play():

CleanShot 2021-12-25 at 21 57 18@2x

What I'm trying to do is load and play a track in one function.

To Reproduce Steps to reproduce the behavior:

const track = {
  id: 0,
  url: "https://storage.googleapis.com/audyo-staging/audyo/f85fb18d-5a2b-48d8-a15d-54801ce6a2cd.m3u8",
  title: "Mock Title 1",
  artist: "Mock Artist 1",
  duration: 553.728,
};

await TrackPlayer.add(track);
await TrackPlayer.play();

Environment

Result from react-native info:

System:
    OS: macOS 12.0.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 9.62 GB / 64.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.13.0 - /var/folders/sc/f3fjtvms7rdgp3k39mm3gd940000gn/T/yarn--1640469590047-0.2198334877982071/node
    Yarn: 1.22.17 - /var/folders/sc/f3fjtvms7rdgp3k39mm3gd940000gn/T/yarn--1640469590047-0.2198334877982071/yarn
    npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
    Watchman: 2021.12.20.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.11.2 - /opt/homebrew/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3
    Android SDK: Not Found
  IDEs:
    Android Studio: Not Found
    Xcode: 13.2/13C90 - /usr/bin/xcodebuild
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: 0.66.4 => 0.66.4
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

What react-native-track-player version are you using? 2.1.2

Are you testing on a real device or in the simulator? Which OS version are you running?

The behavior is the same on both. The iOS version is 15.2.

Code Please, share the code that is causing the issue

const track = {
  id: 0,
  url: "https://storage.googleapis.com/audyo-staging/audyo/f85fb18d-5a2b-48d8-a15d-54801ce6a2cd.m3u8",
  title: "Mock Title 1",
  artist: "Mock Artist 1",
  duration: 553.728,
};

await TrackPlayer.add(track);
await TrackPlayer.play();

colinricardo avatar Dec 25 '21 22:12 colinricardo

I had the exact same bug on iOS (Android worked perfectly fine for me). For me using the suggested approach in this issue - setting waitForBuffer to true - fixed this bug for me. Have you already tried that?

The description for waitForBuffer in API Docs states: "Indicates whether the player should automatically delay playback in order to minimize stalling. If you notice that network media immediately pauses after it buffers, setting this to true may help."

KochMario avatar Jan 06 '22 11:01 KochMario

Hi @colinricardo, could you provide an update on this? Any luck with the above fix?

@KochMario thanks for referencing this. Do the docs need updating to better reflect this use case/problem? If so is it possible for you to create a PR? Thank you!

bradfloodx avatar Jan 13 '22 04:01 bradfloodx

Hi I'm experiencing same problem only on iOS. We are using radio streams from radio.co. This is a sample stream: https://streaming.radio.co/s5c5da6a36/listen Sometimes is works fine on iOS but other times not...same app/device etc. playing-ready-buffering-paused I use trackplayer 1.2.7 TrackPlayer.setupPlayer({ waitForBuffer: true, playBuffer: 5}) TrackPlayer.add( "https://streaming.radio.co/s5c5da6a36/listen " )

Our app's key feature is listening to audio streams so what can we do? I can't find any log that point me in the right direction.

jr00n avatar Jan 14 '22 18:01 jr00n

I had the same issue, for a quick workaround i used the following process :

  1. listen to paused event, when fired i check a userDidPause flag if false i recall TrackPlayer.play()
  2. listen to playing event, when fired i set userDidPause to false
  3. when the user actually pauses (whenever i call TrackPlayer.pause()) i set userDidPause to true (to ignore the condition at paused event) here is a sample of the code :
// PlaybackState event listener
TrackPlayer.addEventListener(Event.PlaybackState, event => {
    if (event.state === State.Playing) {
        // When playing set userDidPause to false
        this.userDidPause = false;
    }
    else if (event.state === State.Paused) {
        //IF NOT PAUSED BY THE USER (IN CASE OF ISSUE) FORCE RETRY
        if (this.userDidPause === false) {
            TrackPlayer.play();
        }
    }
})

// set this.userDidPause to true before calling TrackPlayer.pause()
pause() {
   this.userDidPause = true;
   TrackPlayer.pause();
}

drhootch avatar Jan 17 '22 08:01 drhootch

Thanks @drhootch but that workaround is causing sometimes a loop between buffering, pause, (forced) play, buffering, pause etc...so not working for me. It's only causing problems with mp3 audio (radio stream) via http

jr00n avatar Feb 19 '22 20:02 jr00n

I am using [email protected], I've tried waitForBuffer: true and also @drhootch 's workaround but nothing works for me. This is the code

  const buffer = 2;
  await TrackPlayer.setupPlayer({
      waitForBuffer: true,
      playBuffer: buffer,
      minBuffer: buffer * 2,
      maxBuffer: buffer * 2,
   });
 TrackPlayer.updateOptions({
      capabilities: [
        Capability.Play,
        Capability.Stop,
        Capability.Pause,
        Capability.SeekTo,
        Capability.Skip,
      ],
      compactCapabilities: [
        Capability.Play,
        Capability.Stop,
        Capability.Pause,
        Capability.SeekTo,
        Capability.Skip,
      ],
      notificationCapabilities: [
        Capability.Play,
        Capability.Stop,
        Capability.Pause,
        Capability.SeekTo,
        Capability.Skip,
      ],
    });
   await TrackPlayer.add({
    id: 0,
    title: "Focus",
    artist: "Se Therapies",
    url:
      "https://firebasestorage.googleapis.com/v0/b/octacoil-app.appspot.com/o/Focus.m4a?alt=media&token=3de11cd26008-4744-9f31-b0605a575f4e",
  });

and then when the user taps the song I play it using

await TrackPlayer.play();

manav-kasare avatar Mar 03 '22 12:03 manav-kasare

@manav-kasare @jr00n @colinricardo @KochMario ,

Can you please see if this issue is present in v2.2.0-rc3? If it is please submit a minimum reproducable example repo (you can use the example project on the feature/kotlinaudio branch).

jspizziri avatar Apr 13 '22 14:04 jspizziri

@jspizziri Yes this issue still exists in v2.2.0-rc3

SergiOnGit avatar Apr 28 '22 11:04 SergiOnGit

Guys make sure on IOS that you set the artist otherwise the track won't start.

abdouAoufi avatar Jul 19 '22 07:07 abdouAoufi

Closing, as I believe this is being addressed on https://github.com/doublesymmetry/react-native-track-player/issues/1691

If anyone disagrees please let me know and I can reopen.

jspizziri avatar Sep 06 '22 16:09 jspizziri

I had the same issue, for a quick workaround i used the following process :

  1. listen to paused event, when fired i check a userDidPause flag if false i recall TrackPlayer.play()
  2. listen to playing event, when fired i set userDidPause to false
  3. when the user actually pauses (whenever i call TrackPlayer.pause()) i set userDidPause to true (to ignore the condition at paused event) here is a sample of the code :
// PlaybackState event listener
TrackPlayer.addEventListener(Event.PlaybackState, event => {
    if (event.state === State.Playing) {
        // When playing set userDidPause to false
        this.userDidPause = false;
    }
    else if (event.state === State.Paused) {
        //IF NOT PAUSED BY THE USER (IN CASE OF ISSUE) FORCE RETRY
        if (this.userDidPause === false) {
            TrackPlayer.play();
        }
    }
})

// set this.userDidPause to true before calling TrackPlayer.pause()
pause() {
   this.userDidPause = true;
   TrackPlayer.pause();
}

@drhootch this solution works for me, though it does pause it momentarily prior to replaying

mmckinley8 avatar Apr 12 '23 19:04 mmckinley8