Skip to content

stuck the slider #100

@priyans1501

Description

@priyans1501

in my music player code when i try to drag the slider and when i release the slider thum then my slider and current time duration is stucked at where i relese the thum and when i pause and resume the song then i back on cureent time and start normally how to solve that issue ?

import { Alert, PanResponder, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import React, { useEffect, useState, useRef } from 'react';
import Sound from 'react-native-sound';
import Slider from '@react-native-community/slider';
import { stopCurrentSound, setCurrentSound, getCurrentSound } from './AudioManager';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import AntDesign from 'react-native-vector-icons/AntDesign';
import LottieView from 'lottie-react-native';
import systemSetting from 'react-native-system-setting';
import { Slider as Aws } from 'react-native-awesome-slider';
import { useSharedValue } from 'react-native-reanimated';

export default function MusicPlayer({ route, navigation }) {
const { song, allSongs, currentIndex } = route.params;
const [isPlaying, setIsPlaying] = useState(false);
const [duration, setDuration] = useState(0);
const [currentTime, setCurrentTime] = useState(0);
const [currentSong, setCurrentSong] = useState(song);
const [songIndex, setSongIndex] = useState(currentIndex);
const [volume, setVolume] = useState(0.5);
const [isSeeking, setIsSeeking] = useState(false);

const timerRef = useRef(null);
const animationRef = useRef(null);
const volumeListenerRef = useRef(null);
const SKIP_TIME = 10;

const progress = useSharedValue(0);
const min = useSharedValue(0);
const max = useSharedValue(duration);

useEffect(() => {
    progress.value = currentTime;
}, [currentTime]);

useEffect(() => {
    max.value = duration;
}, [duration]);

useEffect(() => {
    const initVolume = async () => {
        try {
            const initialVolume = await systemSetting.getVolume();
            setVolume(initialVolume);

            volumeListenerRef.current = systemSetting.addVolumeListener((data) => {
                const newVolume = data.value;
                setVolume(newVolume);
                const sound = getCurrentSound();
                if (sound) {
                    sound.setVolume(newVolume);
                }
            });
        } catch (error) {
            console.error('Volume initialization error:', error);
            setVolume(0.5);
        }
    };

    const unsubscribe = navigation.addListener('beforeRemove', () => {
        stopCurrentSound();
        clearInterval(timerRef.current);
        if (volumeListenerRef.current) {
            systemSetting.removeVolumeListener(volumeListenerRef.current);
        }
    });

    playAudio(currentSong.path);
    initVolume();

    return () => {
        unsubscribe();
        stopCurrentSound();
        clearInterval(timerRef.current);
        if (volumeListenerRef.current) {
            systemSetting.removeVolumeListener(volumeListenerRef.current);
        }
    };
}, [currentSong, navigation]);

useEffect(() => {
    if (isPlaying && animationRef.current) {
        animationRef.current.play();
    } else if (animationRef.current) {
        animationRef.current.pause();
    }
}, [isPlaying]);

const startTimer = (sound) => {
    if (timerRef.current) {
        clearInterval(timerRef.current);
    }

    timerRef.current = setInterval(() => {
        if (!isSeeking && sound && sound.isLoaded()) {
            sound.getCurrentTime((seconds) => {
                if (!isSeeking) {
                    setCurrentTime(Math.floor(seconds));
                }
            });
        }
    }, 250);
};

const playAudio = (filePath) => {
    stopCurrentSound();
    clearInterval(timerRef.current);

    const sound = new Sound(filePath, '', (error) => {
        if (error) {
            console.log('Error loading audio:', error);
            Alert.alert('Error', 'Failed to load the audio file');
            return;
        }

        setDuration(sound.getDuration());
        setCurrentSound(sound);
        sound.setVolume(volume);

        sound.play((success) => {
            if (success) {
                setIsPlaying(false);
                clearInterval(timerRef.current);
                setCurrentTime(0);
                playNextTrack();
            } else {
                Alert.alert('Error', 'Error playing audio');
            }
        });

        setIsPlaying(true);
        startTimer(sound);
    });
};

const togglePlayPause = () => {
    const sound = getCurrentSound();
    if (!sound) return;

    if (isPlaying) {
        sound.pause();
        clearInterval(timerRef.current);
        setIsPlaying(false);
    } else {
        sound.play((success) => {
            if (success) {
                setIsPlaying(false);
                clearInterval(timerRef.current);
                setCurrentTime(0);
                playNextTrack();
            } else {
                Alert.alert('Error', 'Error playing audio');
            }
        });
        setIsPlaying(true);
        startTimer(sound);
    }
};

const forward = () => {
    const sound = getCurrentSound();
    if (!sound) return;

    sound.getCurrentTime((seconds) => {
        const newTime = Math.min(seconds + SKIP_TIME, duration);
        sound.setCurrentTime(newTime);
        setCurrentTime(newTime);
    });
};

const backward = () => {
    const sound = getCurrentSound();
    if (!sound) return;

    sound.getCurrentTime((seconds) => {
        const newTime = Math.max(seconds - SKIP_TIME, 0);
        sound.setCurrentTime(newTime);
        setCurrentTime(newTime);
    });
};

const playNextTrack = () => {
    if (!allSongs || allSongs.length === 0) return;

    const nextIndex = (songIndex + 1) % allSongs.length;
    const nextSong = allSongs[nextIndex];

    setSongIndex(nextIndex);
    setCurrentSong(nextSong);
};

const playPreviousTrack = () => {
    if (!allSongs || allSongs.length === 0) return;

    const prevIndex = songIndex === 0 ? allSongs.length - 1 : songIndex - 1;
    const prevSong = allSongs[prevIndex];

    setSongIndex(prevIndex);
    setCurrentSong(prevSong);
};

const onSeekStart = (value) => {
    setIsSeeking(true);
    clearInterval(timerRef.current);
};

const onSeek = (value) => {
    progress.value = value;
    setCurrentTime(value);
};

const onSeekEnd = (value) => {
    const sound = getCurrentSound();
    if (sound) {
        sound.setCurrentTime(value);
        setCurrentTime(value);
        setIsSeeking(false);

        if (isPlaying) {
            startTimer(sound);
        }
    }
};

const onVolumeChangeComplete = async (value) => {
    try {
        const sound = getCurrentSound();
        if (sound) {
            sound.setVolume(value);
        }
        await systemSetting.setVolume(value);
        setVolume(value);
    } catch (error) {
        console.error('Error setting volume:', error);
        const sound = getCurrentSound();
        if (sound) {
            sound.setVolume(value);
            setVolume(value);
        }
    }
};

const formatTime = (seconds) => {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
};

return (
    <View style={styles.container}>
        <TouchableOpacity
            style={styles.backButton}
            onPress={() => navigation.goBack()}
        >
            <MaterialCommunityIcons name="arrow-left" size={30} color="white" />
        </TouchableOpacity>

        <View style={styles.playerContainer}>
            <View style={styles.contentContainer}>
                <View style={styles.animationContainer}>
                    <LottieView
                        ref={animationRef}
                        style={styles.animation}
                        source={require('../../../assets/animation/song.json')}
                        autoPlay={false}
                        loop={true}
                    />
                </View>

                <View style={styles.volumeContainer}>
                    <Slider
                        style={styles.volumeSlider}
                        minimumValue={0}
                        maximumValue={1}
                        value={volume}
                        onSlidingComplete={onVolumeChangeComplete}
                        minimumTrackTintColor="#1DB954"
                        maximumTrackTintColor="#555555"
                        thumbTintColor="#FFFFFF"
                    />
                    <MaterialCommunityIcons
                        name={volume === 0 ? "volume-mute" : volume < 0.5 ? "volume-medium" : "volume-high"}
                        size={20}
                        color="#1DB954"
                    />
                </View>
            </View>

            <View style={styles.infoContainer}>
                <Text style={styles.songNameText} numberOfLines={2}>
                    {currentSong.name}
                </Text>
            </View>

            <View style={styles.seekBarContainer}>
                {/* <Slider
                    style={styles.seekBar}
                    minimumValue={0}
                    maximumValue={duration}
                    value={isSeeking ? seekTime : currentTime}
                    onSlidingStart={onSeekStart}
                    onValueChange={onSeek}
                    onSlidingComplete={onSeekEnd}
                    minimumTrackTintColor="#1DB954"
                    maximumTrackTintColor="#555555"
                    thumbTintColor="#FFFFFF"
                /> */}
                <Aws
                    minimumValue={min}
                    maximumValue={max}
                    style={styles.seekBar}
                    progress={progress}
                    onSlidingStart={onSeekStart}
                    onSlidingComplete={onSeekEnd}
                    onValueChange={onSeek}
                    theme={{
                        minimumTrackTintColor: '#1DB954',
                        maximumTrackTintColor: '#555555',

                    }}
                    thumbWidth={15}
                    bubble={formatTime}
                    heartbeat={true}
                />
                <View style={styles.timeContainer}>
                    <Text style={styles.timeText}>{formatTime(currentTime)}</Text>
                    <Text style={[styles.timeText, { marginLeft: 255 }]}>{formatTime(duration)}</Text>
                </View>
            </View>

            <View style={styles.controlsContainer}>
                <TouchableOpacity
                    onPress={playPreviousTrack}
                    style={styles.controlButton}
                >
                    <MaterialCommunityIcons name="skip-previous" size={35} color="white" />
                </TouchableOpacity>
                <TouchableOpacity onPress={backward} style={styles.controlButton}>
                    <AntDesign name="banckward" size={24} color="white" />
                </TouchableOpacity>
                <TouchableOpacity
                    onPress={togglePlayPause}
                    style={styles.playPauseButton}
                >
                    <MaterialCommunityIcons name={isPlaying ? 'pause' : 'play'} size={30} color="black" />
                </TouchableOpacity>
                <TouchableOpacity onPress={forward} style={styles.controlButton}>
                    <AntDesign name="forward" size={24} color="white" />
                </TouchableOpacity>
                <TouchableOpacity
                    onPress={playNextTrack}
                    style={styles.controlButton}
                >
                    <MaterialCommunityIcons name="skip-next" size={35} color="white" />
                </TouchableOpacity>
            </View>
        </View>
    </View>
);

}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#121212',
},
backButton: {
position: 'absolute',
top: 10,
left: 15,
padding: 8,
},
playerContainer: {
flex: 1,
justifyContent: 'space-between',
alignItems: 'center',
paddingTop: 100,
paddingBottom: 50,
},
contentContainer: {
width: '100%',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
},
animationContainer: {
width: 300,
height: 300,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 10,
borderRadius: 30,
backgroundColor: '#1E1E1E',
},
animation: {
width: '100%',
height: '100%',
},
volumeContainer: {
position: 'absolute',
flexDirection: 'column',
alignItems: 'center',
right: 20,
bottom: 0
},
volumeSlider: {
transform: [{ rotate: '-90deg' }],
width: 120,
height: 100,
},
infoContainer: {
width: '80%',
alignItems: 'center',
marginBottom: 10,
},
songNameText: {
fontSize: 20,
fontWeight: 'bold',
color: 'white',
textAlign: 'center',
marginBottom: 5,
},
seekBarContainer: {
width: '90%',
marginBottom: 2,
paddingHorizontal: 10,
},
seekBar: {
width: '100%',
height: 40,
marginBottom: 10,
},
timeContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
paddingHorizontal: 5,
},
timeText: {
color: '#B3B3B3',
fontSize: 12,
width: 45,
},
controlsContainer: {
flexDirection: 'row',
justifyContent: 'space-evenly',
alignItems: 'center',
width: '100%',
paddingHorizontal: 20,
},
controlButton: {
padding: 15,
},
playPauseButton: {
backgroundColor: '#1DB954',
padding: 18,
borderRadius: 40,
marginHorizontal: 20,
},
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions