Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] The example code for setting up the player is complicated and docs are insufficient - can you take the example setup code and productize it? #2344

Open
eedeebee opened this issue Jul 18, 2024 · 3 comments

Comments

@eedeebee
Copy link

Context
These thoughts were triggered by my receiving an error in the field that is On Android the app must be in the foreground when setting up the player. and my realizing the code I have in index.js isn't sufficient (or perhaps incorrect) for robust rntp initialization.

I offer it below as an example with my app's other index.js goo left in (sorry).

What is the need and use case of this feature?
The code in the example app here for setting up the player is complicated and the requirements are not really explained in the documentation (e.g., handling of initialization failures and retries). The published docs on how to set things up should be sufficient to cover what to do for your app to be robust in production, but they aren't.

Describe the ideal solution
I would suggest re-working the initialization APIs and/or creating a higher level, simple API call or perhaps two. (This is par for the course for almost every other library.) One could define an object that takes in the information you need for initialization and then abstract away the complexity in the example as much as possible.

The code here is what I'm talking about. At one end of the spectrum, you could just move the example code into the library itself or some version of it that is slightly more general purpose.

Relatedly, with today's APIs, it's not clear the requirements are for ordering and timing of registering the playback service and setupPlayer. Which one needs to happen when? Updating the docs for that would be a helpful step.

Sample insufficient initialization code of mine

/**
 * @format
 */

import {AppRegistry} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import App from './src/App';
import {name as appName} from './app.json';
import TrackPlayer, { IOSCategoryOptions, AppKilledPlaybackBehavior } from 'react-native-track-player';

import { QueryClient } from '@tanstack/react-query';
import AsyncStorage from '@react-native-async-storage/async-storage'
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister'
import 'react-native-url-polyfill/auto';
import 'react-native-get-random-values';

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      gcTime: Infinity, // Let's hold things forever
    },
  },
});
const asyncStoragePersister = createAsyncStoragePersister({
  storage: AsyncStorage,
  key: "tanstack"
});

const NotewizeApp = () => (
    <NavigationContainer>
      <PersistQueryClientProvider client={queryClient} persistOptions={{ persister: asyncStoragePersister }}>
        <App/>
      </PersistQueryClientProvider>
    </NavigationContainer>
  );

AppRegistry.registerComponent(appName, () => NotewizeApp);

async function setupTrackPlayerAndLoadModel() {
  TrackPlayer.registerPlaybackService(() => require('./src/components/pages/Player/service.js'));
  await TrackPlayer.setupPlayer({
    iosCategoryOptions: [IOSCategoryOptions.AllowBluetoothA2DP]
  });
  await TrackPlayer.updateOptions({
    android: {
        appKilledPlaybackBehavior: AppKilledPlaybackBehavior.StopPlaybackAndRemoveNotification
    },
  });
  await TrackPlayer.setVolume(0.5);
  const chord = require("./android/app/src/main/res/raw/notewize_chord.mp3");
  await TrackPlayer.add({
    url: chord
  });
  TrackPlayer.play();

  await Audio.loadModel();
} 

setupTrackPlayerAndLoadModel();


Copy link
Contributor

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 github-actions bot added the Stale label Oct 17, 2024
@eedeebee
Copy link
Author

I believe this issue remains open. If someone could explain what is required here wrt properly initializating rntp, I'm more than happy to write some doc.

@lovegaoshi
Copy link
Contributor

hard to say what happens with your setup code without some serious attention. but the general workflow (android) is:

  1. TP.setupPlayer from MusicModule (ie. the native module) starts MusicService, binds to it and set a connected flag on;
  2. most other TP methods require this connection, otherwise will reject with The player is not initialized. Call setupPlayer first

because of this it is advised to call TP.setupPlayer ASAP so any other TP calls can actually work.

I've never seen On Android the app must be in the foreground when setting up the player. typically people, including the example app, awaits TP.setupPlayer in whatever splash screen they set up. in the example app this is useSetupPlayer and nothing mounts until this hook returns ready.

these errors and retries are there because android is notorious for changing requirements over versions (in a way, becoming more secure as well). This lib dates from 2018. Although I can tell you the particular error you mention, On Android the app must be in the foreground when setting up the player. is largely irrelevant currently. It is correct that a background activity can no longer start a service, but MusicService, as a declared foreground service, should already be started by the system as app starts. This is somewhat illustrated in my recent discovery of the headless start capability.

@github-actions github-actions bot removed the Stale label Oct 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants