psquizzle
psquizzle

Reputation: 185

react-native-track-player Play one song and stop / await user input implementation

I am trying to use react-native-track-player in my app. The functionality of my app requires that one audio track is played, and then it needs to await user input.

I have tried the following code however it leads to laggy and unpredictable behaviour. Is there a way to natively implement pause after each track?

  useTrackPlayerEvents([Event.PlaybackTrackChanged], async event => {
    
    if(!autoplay&&appStateVisible==='active'){
      TrackPlayer.pause();
      TrackPlayer.seekTo(0)
    } else {
      setAutoplay(false)
    }
    if (
      event.type === Event.PlaybackTrackChanged &&
      event.nextTrack !== undefined
    ) {

      const track = await TrackPlayer.getTrack(event.nextTrack);
  
      const currentTrack = await TrackPlayer.getCurrentTrack();
      const {title, artist, artwork} = track || {};
      console.log(track)
      setTrackTitle(title);
      setTrackArtist(artist);
      setTrackArtwork(artwork);
      setTrackNumber(currentTrack)
 
    }
  });

Here is my service.js that will run in background mode.

import TrackPlayer, { Event, State } from "react-native-track-player";
import { AppState } from "react-native";
import React, { Component, useState, useEffect, useRef } from "react";

let wasPausedByDuck = false;
var appState = null;
var autoplay = false;

const subscription = AppState.addEventListener("change", (nextAppState) => {
  if (
    appState &&
    appState.match(/inactive|background/) &&
    nextAppState === "active"
  ) {
    console.log("App has come to the foreground!");
  }

  appState = nextAppState;

  console.log("AppState service", appState);
});

module.exports = async function setup() {
  TrackPlayer.addEventListener(Event.PlaybackTrackChanged, async () => {
    if (!autoplay && appState === "background") {
      await TrackPlayer.pause();
      await TrackPlayer.seekTo(0);
    } else {
      autoplay = false;
    }
  });
  TrackPlayer.addEventListener(Event.PlaybackState, (x) => {
  });

  TrackPlayer.addEventListener(Event.RemotePause, () => {
    TrackPlayer.pause();
  });

  TrackPlayer.addEventListener(Event.RemotePlay, () => {
    TrackPlayer.seekTo(0);
    TrackPlayer.play();
  });

  TrackPlayer.addEventListener(Event.RemoteNext, async () => {
    autoplay = true;

    await TrackPlayer.skipToNext();
    await TrackPlayer.play();
  });

  function isEven(x) {
    return x % 2 == 0;
  }

  TrackPlayer.addEventListener(Event.RemotePrevious, async () => {
    const currentTrack = await TrackPlayer.getCurrentTrack();
    const playbackState = await TrackPlayer.getState();
    const position = await TrackPlayer.getPosition();
    const isPrompt = isEven(currentTrack);

    if (playbackState === "playing") {
      if (position > 2) {
        TrackPlayer.seekTo(0);
      } else {
        if (currentTrack !== 0) {
          if (!isPrompt) {
            TrackPlayer.skipToPrevious();
          } else {
            TrackPlayer.skip(currentTrack - 2);
          }
        } else {
          TrackPlayer.seekTo(0);
        }
      }
    } else {
      if (currentTrack !== 0) {
        if (!isPrompt) {
          autoplay = true;
          TrackPlayer.skipToPrevious();
          TrackPlayer.play();
        } else {
          autoplay = true;
          TrackPlayer.skip(currentTrack - 2);
          TrackPlayer.play();
        }
      } else {
        TrackPlayer.seekTo(0);
        TrackPlayer.play();
      }
    }
  });

  TrackPlayer.addEventListener(Event.RemoteDuck, async (e) => {
    if (e.permanent === true) {
      TrackPlayer.stop();
    } else {
      if (e.paused === true) {
        const playerState = await TrackPlayer.getState();
        wasPausedByDuck = playerState !== State.Paused;
        TrackPlayer.pause();
      } else {
        if (wasPausedByDuck === true) {
          TrackPlayer.play();
          wasPausedByDuck = false;
        }
      }
    }
  });
};


Upvotes: 0

Views: 2968

Answers (1)

psquizzle
psquizzle

Reputation: 185

In response to this question on the react-native-track-player support discord from answered by jspizziri, who suggested adding one track to the queue at a time. I implemented this using a playlist ref and index ref and essentially controlling the player externally.

Upvotes: 0

Related Questions