Reputation: 185
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
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