doublesymmetry / react-native-track-player

A fully fledged audio module created for music apps. Provides audio playback, external media controls, background mode and more!
https://rntp.dev/
Apache License 2.0
3.18k stars 981 forks source link

Android 14 - TypeError: Cannot read property 'then' of undefined, js engine: hermes #2205

Closed shahzore-qureshi closed 6 months ago

shahzore-qureshi commented 7 months ago

Describe the Bug When calling the function below:

await TrackPlayer.setupPlayer();

the error below occurs:

TypeError: Cannot read property 'then' of undefined, js engine: hermes

After this error is closed, everything seems to work fine.

Here is a screenshot:

image

Steps To Reproduce Run TrackPlayer.setupPlayer() on Android 14 (API Level 34) in a Pixel 3a emulator provided by Android Studio. This error occurred on a 2023 MacBook Air M2.

Code To Reproduce

import React, { useEffect } from 'react';
import { View } from 'react-native';
import TrackPlayer from 'react-native-track-player';

export const TestScreen = () => {
  useEffect(() => {
    // eslint-disable-next-line @typescript-eslint/no-floating-promises
    (async () => {
      await TrackPlayer.setupPlayer();
      // await TrackPlayer.add([{ url: require('~/assets/audio/coffee.mp3') }]);
      // await TrackPlayer.play();
      // setTimeout(() => {
      //   TrackPlayer.stop().catch(() => {});
      // }, 9000);
    })();
  }, []);

  return <View />;
};

Replicable on Example App? Can you replicate this bug in the React Native Track Player Example App? I have not tried. I will go ahead, try right away and then update this ticket.

Environment Info: Paste the results of npx react-native info:

System:
  OS: macOS 14.1
  CPU: (8) arm64 Apple M2
  Memory: 80.94 MB / 24.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.12.1
    path: ~/.nvm/versions/node/v18.12.1/bin/node
  Yarn:
    version: 1.22.19
    path: ~/.nvm/versions/node/v18.12.1/bin/yarn
  npm:
    version: 8.19.2
    path: ~/.nvm/versions/node/v18.12.1/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.14.2
    path: /Users/shahzore/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - watchOS 10.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.11005911
  Xcode:
    version: 15.0.1/15A507
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.6
    path: /usr/bin/javac
  Ruby:
    version: 2.7.4
    path: /Users/shahzore/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: ^18.2.0
  react-native:
    installed: 0.72.6
    wanted: ^0.72.6
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

Paste the exact react-native-track-player version you are using: 4.0.1-nightly-a0fdd21f77afb4c11cb7062c6665dfd337cef117

Real device? Or simulator? Simulator (Android 14 (API Level 34) in a Pixel 3a emulator provided by Android Studio)

What OS are you running? macOS Sonoma 14.1

How I can Help What can you do to help resolve this? I am willing to try any steps provided by the community to help resolve this. For now, I'll go ahead and ignore the error since it does not seem to break any functionality.

Have you investigated the underlying JS or Swift/Android code causing this bug? I have not. However, I can certainly do that.

Can you create a Pull Request with a fix? Sure!

lovegaoshi commented 7 months ago

the android example app on android 14 should only give a cycling dependency warning and another image warning, likely could be your setup

shahzore-qureshi commented 6 months ago

I forgot to update this issue - I was able to resolve this issue by changing how I initialized the player. Here is my index.js file:

import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import { playbackService } from './musicPlayerServices';
import TrackPlayer from 'react-native-track-player';

AppRegistry.registerComponent(appName, () => App);
TrackPlayer.registerPlaybackService(() => playbackService);

Here is the playbackService function that I imported and passed to the TrackPlayer registration:

export function playbackService() {
  TrackPlayer.addEventListener(Event.RemotePause, () => {
    TrackPlayer.pause()
      .then(() => {})
      .catch(() => {});
  });

  TrackPlayer.addEventListener(Event.RemotePlay, () => {
    TrackPlayer.play()
      .then(() => {})
      .catch(() => {});
  });
  TrackPlayer.addEventListener(Event.PlaybackProgressUpdated, () => {});
}

If you look closely enough, the function is not a Promise. That is why I am getting the error Cannot read property 'then' of undefined. It is because TrackPlayer is expecting a Promise.

To fix this issue, I added "async" in front of the function definition like so:

export async function playbackService() {
  TrackPlayer.addEventListener(Event.RemotePause, () => {
    TrackPlayer.pause()
      .then(() => {})
      .catch(() => {});
  });

  TrackPlayer.addEventListener(Event.RemotePlay, () => {
    TrackPlayer.play()
      .then(() => {})
      .catch(() => {});
  });
  TrackPlayer.addEventListener(Event.PlaybackProgressUpdated, () => {});
}

I hope this helps someone out there!

zakharov-dy commented 5 months ago

I hope this helps someone out there!

Yes, it definitely helped someone (me)