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.31k stars 1.02k forks source link

App crashed in Android, when adding maxBuffer in TrackPlayer.setupPlayer() #2396

Closed fazzee closed 2 weeks ago

fazzee commented 2 weeks ago

Describe the Bug I have this Error in Android and Unable to Initialise the Track Player: The value for maxBuffer should be greater than or equal to minBuffer.

Then I added the maxBuffer and Got this Error, and My App is start Crashed: ERROR Your app just crashed. See the error below. java.lang.NullPointerException com.doublesymmetry.trackplayer.service.MusicService.updateOptions(MusicService.kt:186) com.doublesymmetry.trackplayer.module.MusicModule$updateOptions$1.invokeSuspend(MusicModule.kt:260) kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) android.os.Handler.handleCallback(Handler.java:938) android.os.Handler.dispatchMessage(Handler.java:99) android.os.Looper.loop(Looper.java:263) android.app.ActivityThread.main(ActivityThread.java:8292) java.lang.reflect.Method.invoke(Native Method) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)

Code To Reproduce `static async initialize() { if (Audio.isInitialized) return;

const setupOptionsIOS = {
  minBuffer: 16, // buffer at least 30 seconds of audio before playback
  playBuffer: 3, // buffer at least 30 seconds of audio before playback start/resume, after a user action, like a seek (Android only)
  maxCacheSize: 32768, // cache up to 4MB of audio files (Android only)
  autoHandleInterruptions: true, // automatically handle audio interruptions
  iosCategory: IOSCategory.Playback, // app plays recorded music or other sounds
  iosCategoryMode: IOSCategoryMode.VoiceChat, // app plays audio using text-to-speech, @see https://developer.apple.com/documentation/avfaudio/avaudiosession/mode
  iosCategoryOptions: [IOSCategoryOptions.MixWithOthers], // reduce the volume of other app while audio from this  plays, @see https://developer.apple.com/documentation/avfaudio/avaudiosession/categoryoptions
  androidAudioContentType: AndroidAudioContentType.Music, // app's volume will be lowered during short interruptions, like a message notification (Android only)
};

const setupOptionsAndroid = {
  maxBuffer: 20, // make sure maxBuffer is greater than or equal to minBuffer
  ...setupOptionsIOS,
};

try {
  await TrackPlayer.setupPlayer(Platform.OS === 'android' ? setupOptionsAndroid : setupOptionsIOS);

  await TrackPlayer.updateOptions({
    iosCategoryOptions: [IOSCategoryOptions.DuckOthers, IOSCategoryOptions.InterruptSpokenAudioAndMixWithOthers],
    android: {
      appKilledPlaybackBehavior: AppKilledPlaybackBehavior.StopPlaybackAndRemoveNotification,
    },
    capabilities: [Capability.Play, Capability.Pause, Capability.Stop, Capability.Skip, Capability.SkipToNext, Capability.SkipToPrevious, Capability.JumpBackward, Capability.JumpForward, Capability.Seek],
    CompactCapabilities: [Capability.Play, Capability.Pause, Capability.Stop, Capability.Skip, Capability.SkipToNext, Capability.SkipToPrevious, Capability.JumpBackward, Capability.JumpForward, Capability.Seek],
  });

  // setup event listeners
  //TrackPlayer.addEventListener(Event.PlaybackState, (event) => {
  //logger.debug('Playback state changed.', event.state);
  //});

  TrackPlayer.addEventListener(Event.PlaybackError, (error) => {
    logger.error('Error during playback.', error);
  });

  // clear the queue when we've played the last item in it, to keep it clean and tidy
  TrackPlayer.addEventListener(Event.PlaybackQueueEnded, async ({track}) => {
    const queue = await TrackPlayer.getQueue();
    if (queue.length > 0) {
      await TrackPlayer.reset();
      // remove all tracks up to and including the last played track
      //await TrackPlayer.remove([...Array(track + 1).keys()]);
      const updatedQueue = await TrackPlayer.getQueue();
      logger.debug(`Current queue size is ${updatedQueue.length}.`);
    }
  });

  Audio.isInitialized = true;
  logger.debug('Audio playback initialized successfully.');
} catch (error) {
  logger.emerg('Error initializing audio playback.', error);
}

}`

Environment Info: Paste the results of `info Fetching system and libraries information... System: OS: macOS 14.6.1 CPU: (8) arm64 Apple M2 Memory: 134.00 MB / 8.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 18.19.0 path: ~/.nvm/versions/node/v18.19.0/bin/node Yarn: version: 1.22.22 path: ~/Documents/work/perzimo-health-app/perzimo-mobile/src/mobile/node_modules/.bin/yarn npm: version: 10.6.0 path: ~/.nvm/versions/node/v18.19.0/bin/npm Watchman: Not Found Managers: CocoaPods: version: 1.15.2 path: /Users/macbook/.rvm/gems/ruby-2.7.6/bin/pod SDKs: iOS SDK: Platforms:

info React Native v0.76.1 is now available (your project is running on v0.74.5). info Changelog: https://github.com/facebook/react-native/releases/tag/v0.76.1 info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.74.5 info For more info, check out "https://reactnative.dev/docs/upgrading?os=macos".`

Paste the exact "react-native-track-player": "^4.1.1" Real device? Yes, Oppo A5 2020 and Simulator also (Google Pixel 6) What OS are you running? MacBook Pro M2

How I can Help What can you do to help resolve this?

lovegaoshi commented 2 weeks ago

ur bug is this line: https://github.com/doublesymmetry/react-native-track-player/blob/9ff32f0f5a7b4f96900bf422810d587f5d2e3789/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt#L223

this number is in ms. DEFAULT_MIN_BUFFER_MS is 50000. u have to do some log printing urself to figure out the null pointer part.

puckey commented 2 weeks ago

thanks @lovegaoshi

fazzee commented 2 weeks ago

Hi @lovegaoshi , Yeah I checked your suggestion. I'm using values in seconds as they are saying in their Docs.

await TrackPlayer.setupPlayer({ minBuffer: 60, playBuffer: 60, maxCacheSize: 32768, autoHandleInterruptions: true, iosCategory: IOSCategory.Playback, iosCategoryMode: IOSCategoryMode.VoiceChat, iosCategoryOptions: [IOSCategoryOptions.MixWithOthers], androidAudioContentType: AndroidAudioContentType.Music, })

But this way I'm getting the above error. Can you suggest some setupPlayer configs that used in both Android and iOS without having any errors?

lovegaoshi commented 2 weeks ago

buddy i neither get paid to maintain this lib, nor i actually uses a custom buffer range myself. i know the default works, which is setting both to 50000 ms. the rest its on you. do a couple of log.d