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

Crash Android: No virtual method buildOrThrow() com/google/common/collect/ImmutableMap - Guava Error #2195

Closed theRealSheng closed 4 months ago

theRealSheng commented 8 months ago

Describe the Bug

java.lang.NoSuchMethodError: No virtual method buildOrThrow()Lcom/google/common/collect/ImmutableMap; in class Lcom/google/common/collect/ImmutableMap$Builder; or its super classes (declaration of 'com.google.common.collect.ImmutableMap$Builder' appears in /data/app/~~fuVZZzfovieKT-VMANf3iw==/com.novatradingapp.bbva-_UY_GYgNVi3zyN91WUmOcw==/base.apk!classes7.dex)
    at com.google.android.exoplayer2.audio.AudioCapabilities.<clinit>(AudioCapabilities.java:85)
    at com.google.android.exoplayer2.audio.DefaultAudioSink$Builder.<init>(DefaultAudioSink.java:253)
    at com.google.android.exoplayer2.DefaultRenderersFactory.buildAudioSink(DefaultRenderersFactory.java:633)
    at com.google.android.exoplayer2.DefaultRenderersFactory.createRenderers(DefaultRenderersFactory.java:312)
    at com.google.android.exoplayer2.ExoPlayerImpl.<init>(ExoPlayerImpl.java:256)
    at com.google.android.exoplayer2.ExoPlayer$Builder.build(ExoPlayer.java:1153)
    at com.doublesymmetry.kotlinaudio.players.BaseAudioPlayer.<init>(BaseAudioPlayer.kt:226)
    at com.doublesymmetry.kotlinaudio.players.QueuedAudioPlayer.<init>(QueuedAudioPlayer.kt:18)
    at com.doublesymmetry.trackplayer.service.MusicService.setupPlayer(MusicService.kt:159)
    at com.doublesymmetry.trackplayer.module.MusicModule$onServiceConnected$1.invokeSuspend(MusicModule.kt:57)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7872)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
    Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@f07db0e, Dispatchers.Main]

Steps To Reproduce App calls setupPlayer.

Code To Reproduce

track_player_service.tsx

import { TrackPlayerLib } from '@app/libs/tranck-player-lib';

const {
  TrackPlayer,
  AppKilledPlaybackBehavior,
  Capability,
  RepeatMode,
  Event,
} = TrackPlayerLib;

export const DefaultRepeatMode = RepeatMode.Off;
export const DefaultAudioServiceBehaviour = AppKilledPlaybackBehavior.ContinuePlayback;

const setupPlayer = async (
  options: Parameters<typeof TrackPlayer.setupPlayer>[0]
) => {
  const setup = async () => {
    try {
      return await TrackPlayer.setupPlayer(options);
    } catch (error) {
      console.log('**** setupPlayer error', error);
      return (error as Error & { code?: string }).code;
    }
  };
  setup();
  while ((await setup()) === 'android_cannot_setup_player_in_background') {
    /*
     * A timeout will mostly only execute when the app is in the foreground,
     * and even if we were in the background still, it will reject the promise
     * and we'll try again:
     */
    await new Promise<void>((resolve) => setTimeout(resolve, 1));
  }
};

export const AudioSetupService = async () => {
  await setupPlayer({
    waitForBuffer: true,
    autoHandleInterruptions: true,
  });
  await TrackPlayer.updateOptions({
    android: {
      appKilledPlaybackBehavior: DefaultAudioServiceBehaviour,
    },
    capabilities: [
      Capability.Play,
      Capability.Pause,
      Capability.Stop,
    ],
    compactCapabilities: [
      Capability.Play,
      Capability.Pause,
    ],
  });
  await TrackPlayer.setRepeatMode(DefaultRepeatMode);
};

export const PlaybackService = async () => {
  TrackPlayer.addEventListener(Event.RemotePause, () => {
    console.log('Event.RemotePause');
    TrackPlayer.pause();
  });

  TrackPlayer.addEventListener(Event.RemotePlay, () => {
    console.log('Event.RemotePlay');
    TrackPlayer.play();
  });

  TrackPlayer.addEventListener(Event.RemoteStop, () => {
    console.log('Event.RemoteStop');
    TrackPlayer.reset();
  });
};

Index File

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

Things that could affect:

Android/App/Build.gradlew

configurations { implementation.exclude(group: 'com.google.guava', module: 'guava') implementation.exclude(group: 'com.google.guava', module: 'listenablefuture') implementation.exclude(group: 'com.google.guava', module: 'failureaccess') }

I have tried to fix the guava issue by adding this to the dependecies in the App build.gradlew


   implementation(project(':react-native-track-player')) {
        exclude group: 'com.google.guava', module: 'guava'
        exclude group: 'com.google.android', module: 'exoplayer'
    }

    implementation('com.google.android.exoplayer:exoplayer:2.19.0') {
        exclude group: 'com.google.guava', module: 'guava'
    }

    implementation('com.google.android.exoplayer:extension-mediasession:2.19.0') {
        exclude group: 'com.google.guava', module: 'guava'
    }

    implementation 'com.google.guava:guava:31.1-android'

Replicable on Example App? Yes, if I add the configuration.

Environment Info: System: OS: macOS 13.4 CPU: (12) x64 Apple M2 Max Memory: 1.87 GB / 64.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 19.7.0 - /usr/local/bin/node Yarn: 1.19.1 - /usr/local/bin/yarn npm: 9.5.0 - /usr/local/bin/npm Watchman: 2023.06.12.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.12.1 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4 Android SDK: Not Found IDEs: Android Studio: 2022.1 AI-221.6008.13.2211.9619390 Xcode: 14.3/14E222b - /usr/bin/xcodebuild Languages: Java: 11.0.16.1 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.13 => 0.71.13 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

 "react-native": "0.71.13",
    "react-native-track-player": "^4.0.1",

Emulator, Android

How I can Help com.google.android.exoplayer2 seems to be using guava version lower than 31 which it is causing the problem.

lovegaoshi commented 8 months ago

I believe RNTP has plans to migrate to media3 from exoplayer2, so until then(tm)

github-actions[bot] commented 5 months ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] commented 4 months ago

This issue was closed because it has been stalled for 7 days with no activity.