alantoa / react-native-awesome-slider

🚀 An anwesome <Slider/> that supports various features haptic, lottie, animation, ballon, etc.
MIT License
263 stars 30 forks source link

Audio Player Example #7

Closed Hannes1 closed 2 years ago

Hannes1 commented 2 years ago

Hi, so I was wondering what the best approach will be for hooking the slider up to an audio player (ps I'm using react-native-track-player).

So CurrentPosition prop updates every 100ms (useProgress hook from track player) and while I'm scrubbing I don't want the slider to update based on CurrentPosition anymore so I'm using the progress constant then.

Current Problem: Everything works but when scrubbing is done the slider jumps to prev position and then to new scrub position (Probably because currentposition is still based on prev value and don't update on time)

interface Props {
  duration: number;
  currentPosition: number;
  onSeek: (position: number) => void;
  onSeekComplete: (position: number) => void;
  onSeekStart: () => void;
}
function SeekBar(props: Props) {
  const { duration, currentPosition, onSeek, onSeekComplete, onSeekStart } = props;

  const { colors: Colors } = useTheme();

  const progress = useSharedValue(0.1);
  const min = useSharedValue(0);
  const max = useDerivedValue(() => {
    return duration;
  }, [duration]);

  const isScrubbing = useSharedValue(false);
  const prevProgress = useRef(0);

  const onSlidingComplete = (e: number) => {
    onSeekComplete(e);
    isScrubbing.value = false;
  };
  const onSlidingStart = () => {
    Haptics.selectionAsync();
    onSeekStart();
    prevProgress.current = currentPosition;
  };

  useEffect(() => {
    if (!isScrubbing.value) progress.value = currentPosition;
    if (isScrubbing.value) onSeek(progress.value);
  }, [currentPosition, isScrubbing.value, progress]);

  return (
    <View style={[styles.container]}>
      <View style={[styles.progressContainer]}>
        <Slider
          maximumValue={max}
          minimumValue={min}
          progress={progress}
          onSlidingComplete={onSlidingComplete}
          onSlidingStart={onSlidingStart}
          isScrubbing={isScrubbing}
          sliderHeight={4}
          thumbWidth={15}
          theme={{
            disableMinTrackTintColor: '#fff',
            maximumTrackTintColor: Colors.placeholderText,
            minimumTrackTintColor: Colors.blue,
            bubbleBackgroundColor: '#666',
          }}
          bubble={e => formatTime(e)}
          style={styles.slider}
          containerStyle={{ borderRadius: 2 }}
        />
      </View>
      <Text
        style={[styles.timeLabel, { marginLeft: width * 0.025, color: Colors.text }]}
        numberOfLines={1}
      >
        {formatTime(duration - currentPosition)}
      </Text>
    </View>
  );
}

export default SeekBar;

Sorry you can close this if you want to, was just curious as to what you think would be the best approach

alantoa commented 2 years ago

@Hannes1 Hi! I know what you want, and I had this problem before too. You needs are similar to Video Players. You can see my video player source code, I think it will help you!

https://github.com/alantoa/react-native-reanimated-player/blob/main/src/index.tsx

Hannes1 commented 2 years ago

@alantoa thanks for the great example, updated my code for anyone that comes across this.

efstathiosntonas commented 2 years ago

@Hannes1 thanks for the example, you're using prevProgress ref but you're never actually using it, is this a leftover or it should be used somewhere? Thanks

Hannes1 commented 2 years ago

@Hannes1 thanks for the example, you're using prevProgress ref but you're never actually using it, is this a leftover or it should be used somewhere? Thanks

Hi, I think I tried to use the previous state to prevent to jumping around but in the end I removed it.. any improvement on my code would be appreciated 🙏

efstathiosntonas commented 2 years ago

I've managed to make it not to jump but I think I'm using a different audio player than yours (react-native-audio-player-recorder) and it's slightly different than your implementation. If you want me to share a gist or paste the logic here let me know.

Did you managed to fix it in your end?

edit: in my case I'm using it for audio messages in a chat room so I have an AudioManager.js that takes care of the seeking/play/stop/pause etc because there are multiple audio player instances at the same time on screen.

Gabotron-ES commented 4 months ago

I've managed to make it not to jump but I think I'm using a different audio player than yours (react-native-audio-player-recorder) and it's slightly different than your implementation. If you want me to share a gist or paste the logic here let me know.

Did you managed to fix it in your end?

edit: in my case I'm using it for audio messages in a chat room so I have an AudioManager.js that takes care of the seeking/play/stop/pause etc because there are multiple audio player instances at the same time on screen.

Can you post your code please!

efstathiosntonas commented 4 months ago

@Gabotron-ES there you go: https://gist.github.com/efstathiosntonas/c8ed187dfb19e5474e063c11cfef8adf

if you got any questions leave a comment on gist so this issue remains "clean"