react-native-track-player
react-native-track-player copied to clipboard
Time Position indicator on notification and lock screen has unexpected behaviors
Describe the bug Position indicator on notification and lock screen has unexpected behaviors:
- When start track for the first time. Time Position Indicator is always faster than actual position about 3-4 sec.
- When pause track, Time position at about 2 sec compare to current then back to real position in a flash.
To Reproduce Steps to reproduce the behavior:
- Just play a track, I attached the video bellow
Environment (please complete the following information): Device: Iphone Xs - IOS 14.7.1 Track-player version: 1.2.7
Code Please, share the code that is causing the issue index.js `/**
- @format */
import { AppRegistry } from 'react-native'; import App from './src/App'; import { name as appName } from './app.json'; import TrackPlayer, { CAPABILITY_PLAY, CAPABILITY_PAUSE, CAPABILITY_STOP, CAPABILITY_SEEK_TO, CAPABILITY_JUMP_FORWARD, CAPABILITY_JUMP_BACKWARD, CAPABILITY_SKIP_TO_NEXT, CAPABILITY_SKIP_TO_PREVIOUS, CAPABILITY_SKIP, } from 'react-native-track-player';
AppRegistry.registerComponent(appName, () => App);
TrackPlayer.setupPlayer();
TrackPlayer.updateOptions({
stopWithApp: true,
capabilities: [
CAPABILITY_PLAY,
CAPABILITY_PAUSE,
CAPABILITY_SEEK_TO,
CAPABILITY_STOP,
CAPABILITY_JUMP_FORWARD,
CAPABILITY_JUMP_BACKWARD,
CAPABILITY_SKIP_TO_NEXT,
CAPABILITY_SKIP_TO_PREVIOUS,
CAPABILITY_SKIP,
],
});
TrackPlayer.registerPlaybackService(() => require('./track-player.service'));
Track player:
import React from 'react';
import { Platform } from 'react-native';
import TrackPlayer, {
STATE_PLAYING,
STATE_BUFFERING,
TrackPlayerEvents,
} from 'react-native-track-player';
async function updateTrackNotification() { if (Platform.OS === 'ios') { TrackPlayer.pause(); } TrackPlayer.play(); }
export function useTrackPlayer() { const [isMuted, setIsMuted] = React.useState(false); const volRef = React.useRef(0); const playbackState = TrackPlayer.usePlaybackState(); const progressState = TrackPlayer.useTrackPlayerProgress(); const isPlaying = React.useMemo(() => playbackState === STATE_PLAYING, [ playbackState, ]); const isLoading = React.useMemo(() => playbackState === STATE_BUFFERING, [ playbackState, ]);
const play = React.useCallback(async () => { const [position, duration] = await Promise.all([ TrackPlayer.getPosition(), TrackPlayer.getDuration(), ]); if (Math.floor(duration - position) <= 0) { await TrackPlayer.seekTo(0); } await TrackPlayer.play(); }, []);
const addEventHandler = React.useCallback(() => { TrackPlayer.addEventListener(TrackPlayerEvents.REMOTE_PLAY, play); TrackPlayer.addEventListener(TrackPlayerEvents.REMOTE_PAUSE, () => TrackPlayer.pause(), ); TrackPlayer.addEventListener(TrackPlayerEvents.REMOTE_SEEK, async e => { await TrackPlayer.seekTo(e.position); updateTrackNotification(); }); TrackPlayer.addEventListener(TrackPlayerEvents.REMOTE_STOP, () => TrackPlayer.stop(), ); TrackPlayer.addEventListener(TrackPlayerEvents.REMOTE_NEXT, () => TrackPlayer.skipToNext(), ); TrackPlayer.addEventListener(TrackPlayerEvents.REMOTE_PREVIOUS, () => TrackPlayer.skipToPrevious(), ); TrackPlayer.addEventListener( TrackPlayerEvents.REMOTE_JUMP_BACKWARD, async e => { const position = await TrackPlayer.getPosition(); await TrackPlayer.seekTo(Math.max(position - e.interval, 0)); updateTrackNotification(); }, ); TrackPlayer.addEventListener( TrackPlayerEvents.REMOTE_JUMP_FORWARD, async e => { const [position, duration] = await Promise.all([ TrackPlayer.getPosition(), TrackPlayer.getDuration(), ]); await TrackPlayer.seekTo(Math.min(position + e.interval, duration)); updateTrackNotification(); }, ); }, [play]);
React.useEffect(() => { addEventHandler(); return () => { TrackPlayer.reset(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []);
const addTrack = React.useCallback((url: string, title?: string) => { TrackPlayer.add({ id: url, url, artwork: require('./artwork.png'), }); }, []);
const playOrPause = React.useCallback(async () => { if (isPlaying) { return TrackPlayer.pause(); } await play(); }, [isPlaying, play]); const handleMute = React.useCallback(async () => { if (isMuted) { await TrackPlayer.setVolume(volRef.current); } else { volRef.current = await TrackPlayer.getVolume(); await TrackPlayer.setVolume(0); } setIsMuted(!isMuted); }, [isMuted]);
return { isPlaying, isLoading, progressState, addTrack, playOrPause, handleMute, isMuted, TrackPlayer, updateTrackNotification, }; } `
Same problem
Same on my side, I could look into the native implementation, @dcvz would you be able to point me to any specific part of the code where I should look first?
This one is on my radar, but we're currently focused on the Android rewrite. This library under the hood uses: SwiftAudioEx as its player -- also maintained by us.
That project has its own example where you can test this out. I fixed some issues related to this but maybe not this exactly in this commit: https://github.com/DoubleSymmetry/SwiftAudioEx/commit/77dc8f4ff1ca3f6b4f1676171c472ac1cb6b8d7c
Feel free to poke around and make a PR if you find a fix. Otherwise its on our radar and we'll get to it when we can!
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.
This issue was closed because it has been stalled for 7 days with no activity.
This is fixed in https://github.com/doublesymmetry/react-native-track-player/pull/1713
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.
Closed by https://github.com/doublesymmetry/react-native-track-player/pull/1713