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

Some functionality doesn't work on v5.0.0-alpha0

Open bahmanworld opened this issue 4 months ago • 50 comments

Describe the Bug Some functionality doesn't work on v5.0.0-alpha0

  • Remote actions doesn't work on media notification
  • capabilities doesn't apply on notification

TrackPlayer(newArch) works fine but not as expected like v4.1.1

Environment Info: Expo SDK 54@beta TrackPlayer 5.0.0-alpha0 Device: Real Device Platform: Android 12

Any further updates soon?

bahmanworld avatar Aug 23 '25 11:08 bahmanworld

@bahmanworld , you'll need to be more specific and likely reproduce this first in the example app, as I'm not able to reproduce in the example app. I'll leave this open for a few days, but if I don't get specific repro steps (and probably an example app repro) I'm going to close this issue.

jspizziri avatar Aug 25 '25 12:08 jspizziri

Confirming that I'm running into this issue on the 5.0.0 alpha build

Related Jellify issue

I'll get this reproduced in the example repo 👍

anultravioletaurora avatar Aug 26 '25 12:08 anultravioletaurora

Confirming that I'm running into this issue on the 5.0.0 alpha build

Related Jellify issue

I'll get this reproduced in the example repo 👍

Thank you @anultravioletaurora , I couldn't reproduce the example repo but i know this issue related to react-native-track-player core.

bahmanworld avatar Aug 26 '25 12:08 bahmanworld

@bahmanworld ,

I couldn't reproduce the example repo

Does that mean you've successfully tested the example app and that it's working there? Or does it mean you couldn't successfully run the example app.

jspizziri avatar Aug 26 '25 12:08 jspizziri

Does that mean you've successfully tested the example app and that it's working there? Or does it mean you couldn't successfully run the example app.

the second part; I couldn't run the example app successfully. I got some errors, even on Android Studio while syncing gradle

i think the issue #2508 is similar to mine

Screenshot of notification:

Remote actions doesn't work on media notification capabilities doesn't apply on notification

Screenshot_20250826-160843_Kurdify.png

...
TrackPlayer.updateOptions({
    android: {
      appKilledPlaybackBehavior: AppKilledPlaybackBehavior.ContinuePlayback,
      stopForegroundGracePeriod: 5,
      androidSkipSilence: true,
      shuffle: false,
    },
    notificationCapabilities: [
      Capability.Play,  
      Capability.Pause,
      Capability.Stop,
      Capability.SkipToNext,
      Capability.SkipToPrevious,
      Capability.SeekTo,
    ],
    capabilities: [
      Capability.Play,
      Capability.Pause,
      Capability.Stop,
      Capability.SkipToNext,
      Capability.SkipToPrevious,
      Capability.SeekTo,
    ],
  });
};
...

bahmanworld avatar Aug 26 '25 12:08 bahmanworld

does onMediaButtonEvent fire? whats the intent?

if its real device specific whats the model and android ver? do NOT skip the issue template

=== there are 2 places remote events get fired. 1 is MediaSession - onMediaButtonEvent registered as the MediaSessionCallback. the other is ForwardPlayer - its directly overridden by their counterparts (play, seek, etc).

if mediasessioncallback is not registered, controllers cannot control the session which is likely what u see here. without any logcat traces (not like i can understand them anyways) there wont be any progress made bc who knows whats done

if the mediasession's linked player is not the forwardplayer (eg if you link the underlying exoplayer to mediasession.player, on the car wheel seekNext/Previous will correctly emit to control the exoplayer, but remote events will not emit/any post player control methods u have will fail), simple things will still appear to work as exoplayer with a queue is functional by itself, unless u have some logic associated with the forwardplayer

im more intrigued if u can reproduce specifically in my example bc i cannot on S21 + android 14. otherwise ur welcome to diff my fork with main.

lovegaoshi avatar Aug 26 '25 16:08 lovegaoshi

@lovegaoshi I downloaded the build from here -> https://github.com/lovegaoshi/react-native-track-player/actions/runs/17244531170/artifacts/3855648048

I'm able to reproduce the issue. Lock screen controls don't work.

Only play/pause work in the compact notification player.

The lock screen controls shows the correct state but don't work when tapped.

sohamnakhare avatar Aug 29 '25 13:08 sohamnakhare

@sohamnakhare , I'm not going to accept a reproduction that is based on the artifact of a fork of this library. You need to reproduce it in the /example library directly in this repository if you want me to take you seriously.

jspizziri avatar Aug 29 '25 13:08 jspizziri

like i said i CANNOT REPRODUCE on S21 + android 14. you have to give more details as the device and android version.

https://github.com/user-attachments/assets/5513358c-b961-4fd3-83d6-d51a06a082b2

lovegaoshi avatar Aug 29 '25 13:08 lovegaoshi

@lovegaoshi Interestingly it is working for me in the emulator but not on the device. I'm running it on One Plus Nord 2T.

sohamnakhare avatar Aug 29 '25 14:08 sohamnakhare

@sohamnakhare What version of android?

jspizziri avatar Aug 29 '25 14:08 jspizziri

Android version 14

sohamnakhare avatar Aug 29 '25 14:08 sohamnakhare

this is quickly turning into a device specific problem which nobody here can help. since u have the buggy device pls follow what i posted above: is onMediaButtonEvent firing and if so whats the intent.

On Fri, Aug 29, 2025, 7:18 AM Soham Nakhare @.***> wrote:

sohamnakhare left a comment (doublesymmetry/react-native-track-player#2507) https://github.com/doublesymmetry/react-native-track-player/issues/2507#issuecomment-3237196783

Android version 14

— Reply to this email directly, view it on GitHub https://github.com/doublesymmetry/react-native-track-player/issues/2507#issuecomment-3237196783, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVTZ6GNDK66YR6Q4SPL3QBOK7AVCNFSM6AAAAACEUAED7GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEMZXGE4TMNZYGM . You are receiving this because you were mentioned.Message ID: @.*** com>

lovegaoshi avatar Aug 29 '25 15:08 lovegaoshi

@lovegaoshi it is not working on many Android devices.

@jspizziri I'm able to reproduce the issue on the example in the repo.

Attaching the google drive link of the APK -> https://drive.google.com/file/d/1x6D3FrlERXUvboo-d3HGKHauYHbF8BoT/view

I ran this on android 14 device.

sohamnakhare avatar Sep 03 '25 04:09 sohamnakhare

did i not post a video i CANNOT REPRODUCE on s21 + android 14? chanting the same thing will get nowhere unless u somehow make it reproducible on my device, or u answer my question - is onMediaButtonEvent firing and whats the intent

On Tue, Sep 2, 2025, 9:59 PM Soham Nakhare @.***> wrote:

sohamnakhare left a comment (doublesymmetry/react-native-track-player#2507) https://github.com/doublesymmetry/react-native-track-player/issues/2507#issuecomment-3247689030

@lovegaoshi https://github.com/lovegaoshi it is not working on many Android devices.

@jspizziri https://github.com/jspizziri I'm able to reproduce the issue on the example in the repo.

Attaching the google drive link of the APK -> https://drive.google.com/file/d/1x6D3FrlERXUvboo-d3HGKHauYHbF8BoT/view

I ran this on android 14 device.

— Reply to this email directly, view it on GitHub https://github.com/doublesymmetry/react-native-track-player/issues/2507#issuecomment-3247689030, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVUMSELT422CCR2XYWT3QZYSTAVCNFSM6AAAAACEUAED7GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTENBXGY4DSMBTGA . You are receiving this because you were mentioned.Message ID: @.*** com>

lovegaoshi avatar Sep 03 '25 11:09 lovegaoshi

@sohamnakhare ,

I'm not downloading an APK from your Google Drive and installing it. If you modified anything in the /example app to get your issue, then you should send me a link to your fork containing your changes (however, I've tested with the updateOptions config that you sent above and still can't repro)

Lastly, as @lovegaoshi has already indicated an inability to reproduce it on another device with Android 14 installed. I'm also unable to reproduce the issue on my Pixel with Android 16 installed.

At this point, you're either doing something wrong or this is a device-specific issue (as mentioned previously). You're options are:

  1. Answer @lovegaoshi's question:

    is onMediaButtonEvent firing and whats the intent?

  2. Send the cash required to purchase your exact device and conduct my own testing on it for you.

jspizziri avatar Sep 03 '25 12:09 jspizziri

Image Image

@jspizziri @lovegaoshi I got the lock screen controls working by adding the code above.

How can we handle this better ?

sohamnakhare avatar Sep 07 '25 09:09 sohamnakhare

open a PR then

===

whats described here is pretty interesting - the added code is actually an oversight from main that they didnt copy from my branch. whats commented out, as you can see from my HACK comment above, is specific for android <13 - notification calls onStartCommand but not onMediaButtonEvent.

I'm starting to think ur seeing is, while still a device specific problem, ur device OEM never adapted the android 13 notification style. Unfortunately the only 1+ device i have is a 1+ 7 /android 12 which will be caught by the if i wrote there. other than be cautious not to call onMediaKeyEvent on my pixel devices twice it seems safe enough.

lovegaoshi avatar Sep 08 '25 14:09 lovegaoshi

@sohamnakhare ill leave it to you to open a PR for this.

jspizziri avatar Sep 10 '25 09:09 jspizziri

same issue on Android 15

zeevenn avatar Sep 12 '25 06:09 zeevenn

@zeevenn try adding this to your local Kotlin in node_modules:

https://github.com/doublesymmetry/react-native-track-player/issues/2507#issuecomment-3263616306

jspizziri avatar Sep 12 '25 09:09 jspizziri

Hey there, same issue here. Adding the above code from @sohamnakhare did solve the issue.

tomKFM avatar Sep 17 '25 19:09 tomKFM

@Tom-KAUFFMANN would love a PR

jspizziri avatar Sep 17 '25 19:09 jspizziri

@jspizziri I have raised a PR.

sohamnakhare avatar Sep 17 '25 19:09 sohamnakhare

I think @sohamnakhare is already working on it here

tomKFM avatar Sep 17 '25 19:09 tomKFM

I also have similar problem, I fixed with AI and i want to share with you. First of all i need explain why/how i am using this package.

I am making an app for shoutcast radio station live media player, so my audio will be streaming and live, also i had to update now playing info on native media controller. The Play/Pause button does not work with the streaming, and i tried others solutions too. finally fixed, and down below there is a documentaiton for how you reproduce my fix:

React Native Track Player Setup Guide

Problem Overview

When implementing react-native-track-player v4.1.2 for audio streaming, media controller play/pause buttons in the notification shade and lock screen were not functioning, even though:

  • Media controls were visible in notification and lock screen
  • Now playing metadata was displaying correctly
  • The PlaybackService was properly registered

Pressing play/pause buttons on the media controller had no effect on playback.

Root Cause Analysis

The Issue

react-native-track-player's default configuration uses:

interceptPlayerActionsTriggeredExternally = true

This setting intercepts all media control actions (play, pause, next, previous, stop) and routes them through JavaScript via HeadlessJsTaskService. The flow is:

  1. User presses play/pause on media controller
  2. MediaSession receives the action
  3. Action is intercepted (not executed)
  4. Event is emitted to JavaScript via ReactContext
  5. JavaScript handles the event and calls native methods

The problem: This flow fails when ReactContext is null, which commonly occurs:

  • During service startup
  • When app is backgrounded
  • Before React Native is fully initialized

Evidence from Logs

10-02 19:37:40.850 D MusicService: Media control event received: MediaSessionCallback$PAUSE
10-02 19:37:40.850 D MusicService: Emitting BUTTON_PAUSE (remote-pause) event
10-02 19:37:40.851 E MusicService: ReactContext is null, cannot emit event: remote-pause

The events were being received and emitted, but couldn't reach JavaScript.

The Solution

Architecture Change

Change the architecture to match expo-video's approach: let the underlying MediaSession handle standard actions automatically rather than routing through JavaScript.

Key Configuration Change in MusicService.kt:144:

// BEFORE (BROKEN)
val playerConfig = PlayerConfig(
    interceptPlayerActionsTriggeredExternally = true,  // Routes to JavaScript
    handleAudioBecomingNoisy = true,
    handleAudioFocus = true
)

// AFTER (FIXED)
val playerConfig = PlayerConfig(
    interceptPlayerActionsTriggeredExternally = false,  // Let MediaSession handle automatically
    handleAudioBecomingNoisy = true,
    handleAudioFocus = true
)

How It Works

With interceptPlayerActionsTriggeredExternally = false:

  1. User presses play/pause on media controller
  2. MediaSession receives the action
  3. MediaSession automatically executes the action on the player
  4. Playback state changes immediately
  5. Events are still emitted to JavaScript (when ReactContext is available) for app logic

This approach:

  • ✅ Works immediately, even when ReactContext is null
  • ✅ Provides responsive media controls
  • ✅ Still allows JavaScript to react to events when available
  • ✅ Matches the architecture used by expo-video

Step-by-Step Implementation

1. Modify MusicService.kt

File: node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt

Line 144, change the PlayerConfig:

val playerConfig = PlayerConfig(
    interceptPlayerActionsTriggeredExternally = false,  // Changed from true
    handleAudioBecomingNoisy = true,
    handleAudioFocus = true
)

2. Create Patch File

npx patch-package react-native-track-player

This creates: patches/react-native-track-player+4.1.2.patch

3. Verify postinstall Script

Ensure package.json has:

{
  "scripts": {
    "postinstall": "patch-package"
  }
}

4. Rebuild the App

For Expo Development Build:

npx expo run:android
# or
npx expo run:ios

5. Test Media Controls

  1. Start playing audio
  2. Check notification shade - media controls should appear
  3. Test play/pause button - should work immediately
  4. Test on lock screen - should work
  5. Test when app is backgrounded - should work
  6. Check that now playing metadata updates correctly

Comparison with expo-video

expo-video Architecture

expo-video uses MediaSessionService with automatic action handling:

// ExpoVideoPlaybackService.kt
class ExpoVideoPlaybackService : MediaSessionService() {
    val mediaSession = MediaSession.Builder(this, player)
        .setCallback(VideoMediaSessionCallback())  // Only for custom commands
        .build()
    // MediaSession handles play/pause automatically
}

// VideoMediaSessionCallback.kt
class VideoMediaSessionCallback : MediaSession.Callback {
    override fun onCustomCommand(...) {
        // Only handles custom commands like seek forward/backward
        // No handling of PLAY/PAUSE - MediaSession does it automatically
    }
}

react-native-track-player (Fixed)

Now uses the same pattern:

// MusicService.kt
val playerConfig = PlayerConfig(
    interceptPlayerActionsTriggeredExternally = false,  // Like expo-video
    // ...
)

// Events still emitted to JavaScript when available
scope.launch {
    event.onPlayerActionTriggeredExternally.collect {
        when (it) {
            MediaSessionCallback.PLAY -> emit(MusicEvents.BUTTON_PLAY)
            MediaSessionCallback.PAUSE -> emit(MusicEvents.BUTTON_PAUSE)
            // ... other events
        }
    }
}

Troubleshooting

Issue: Media controls not appearing

Check:

  1. Verify PlaybackService is registered in app.json:
{
  "expo": {
    "plugins": [
      [
        "react-native-track-player",
        {
          "playbackServiceName": "PlaybackService"
        }
      ]
    ]
  }
}
  1. Ensure service is started:
await TrackPlayer.setupPlayer();

Issue: Play/pause still not working

Check:

  1. Verify patch was applied:
cat node_modules/react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt | grep -A2 "val playerConfig"

Should show interceptPlayerActionsTriggeredExternally = false

  1. Rebuild the native app (not just reload):
npx expo run:android
  1. Check logs for ReactContext errors:
adb logcat | grep "ReactContext is null"

Issue: Patch not persisting

Check:

  1. Verify postinstall script runs:
npm run postinstall
  1. Check patch file exists:
ls patches/react-native-track-player+4.1.2.patch
  1. Ensure patch-package is installed:
npm install --save-dev patch-package

Testing Checklist

  • [ ] Media controls appear in notification shade
  • [ ] Media controls appear on lock screen
  • [ ] Play button works when app is backgrounded
  • [ ] Pause button works when app is backgrounded
  • [ ] Next/previous buttons work (if applicable)
  • [ ] Now playing metadata displays correctly
  • [ ] Album art displays correctly
  • [ ] Controls work immediately after app launch
  • [ ] Controls work after cold boot
  • [ ] No "ReactContext is null" errors in logs

Additional Notes

Why This Works

The underlying kotlin-audio library (QueuedAudioPlayer) and Media3's MediaSession are fully capable of handling playback actions natively without JavaScript. By setting interceptPlayerActionsTriggeredExternally = false, we:

  1. Enable immediate response: MediaSession executes actions directly on the player
  2. Remove dependency on ReactContext: No need for JavaScript bridge to be ready
  3. Maintain event emissions: JavaScript still receives events when ReactContext is available
  4. Follow Android best practices: Native media controls should work natively

When to Use This Configuration

Use interceptPlayerActionsTriggeredExternally = false when:

  • Building a radio/streaming app where controls must always work
  • App needs to work immediately after launch
  • Service runs independently of React Native lifecycle
  • Following standard Android media app patterns

Consider interceptPlayerActionsTriggeredExternally = true when:

  • Need custom JavaScript logic before every action
  • App controls the entire playback lifecycle
  • JavaScript is always guaranteed to be running
  • Need to intercept and potentially prevent actions

Future Projects

To reproduce this solution in a new project:

  1. Install react-native-track-player and patch-package
  2. Apply the configuration change in MusicService.kt
  3. Create patch with npx patch-package react-native-track-player
  4. Commit the patch file to version control
  5. Ensure postinstall script is configured

This approach is sustainable across library updates - simply reapply the patch after updating react-native-track-player.

References

NeverGET avatar Oct 02 '25 16:10 NeverGET

@NeverGET I don't get why are you talking about v4 whereas we're trying to fix v5 ? v4 worked perfectly for me, the issue appeared on v5

Anyways, i tried to find the interceptPlayerActionsTriggeredExternally and set it to false as you mentionned, but it didn't fix anything for me

tomKFM avatar Oct 08 '25 08:10 tomKFM

I'm getting the same issue on my end - at least on a OnePlus 9. I migrated from 4.1.2 to v5, and notifications stopped working. I've just tested on a Pixel and everything seems to be working, but for some reason OnePlus isn't playing ball. The notification in the media centre works fine, but not the one on the lockscreen.

Jojocaster avatar Oct 14 '25 18:10 Jojocaster

https://github.com/user-attachments/assets/a43029e5-e737-4142-87f7-023be8e9cef1 @jspizziri I deployed the example code on a OnePlus 9 running Android 14, and I'm encountering an issue where the notification controller is not working as expected.

I've attached a video demonstrating the problem. I also tried all the suggestions mentioned above, but the issue still persists on my end.

muhammadhamza841 avatar Oct 20 '25 10:10 muhammadhamza841

@Jojocaster @muhammadhamza841 Can you test this fix ? It should solve the issue, let me know if it does not

tomKFM avatar Oct 20 '25 12:10 tomKFM