-
Notifications
You must be signed in to change notification settings - Fork 40
Description
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,
},
});