Fix: Audio player skip behavior and range requests
This commit is contained in:
@@ -22,33 +22,75 @@ const AudioPlayer = forwardRef<AudioPlayerRef, AudioPlayerProps>(({ src, unlocke
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [hasPlayedOnce, setHasPlayedOnce] = useState(false);
|
||||
|
||||
const [processedSrc, setProcessedSrc] = useState(src);
|
||||
const [processedUnlockedSeconds, setProcessedUnlockedSeconds] = useState(unlockedSeconds);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('[AudioPlayer] MOUNTED');
|
||||
return () => console.log('[AudioPlayer] UNMOUNTED');
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.pause();
|
||||
audioRef.current.currentTime = startTime;
|
||||
setIsPlaying(false);
|
||||
setProgress(0);
|
||||
setHasPlayedOnce(false); // Reset for new segment
|
||||
onHasPlayedChange?.(false); // Notify parent
|
||||
// Check if props changed compared to what we last processed
|
||||
const hasChanged = src !== processedSrc || unlockedSeconds !== processedUnlockedSeconds;
|
||||
|
||||
if (autoPlay) {
|
||||
const playPromise = audioRef.current.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise
|
||||
.then(() => {
|
||||
setIsPlaying(true);
|
||||
onPlay?.();
|
||||
setHasPlayedOnce(true);
|
||||
onHasPlayedChange?.(true); // Notify parent
|
||||
})
|
||||
.catch(error => {
|
||||
console.log("Autoplay prevented:", error);
|
||||
setIsPlaying(false);
|
||||
});
|
||||
if (hasChanged) {
|
||||
audioRef.current.pause();
|
||||
|
||||
let startPos = startTime;
|
||||
|
||||
// If same song but more time unlocked, start from where previous segment ended
|
||||
if (src === processedSrc && unlockedSeconds > processedUnlockedSeconds) {
|
||||
startPos = startTime + processedUnlockedSeconds;
|
||||
}
|
||||
|
||||
const targetPos = startPos;
|
||||
audioRef.current.currentTime = targetPos;
|
||||
|
||||
// Ensure position is set correctly even if browser resets it
|
||||
setTimeout(() => {
|
||||
if (audioRef.current && Math.abs(audioRef.current.currentTime - targetPos) > 0.5) {
|
||||
audioRef.current.currentTime = targetPos;
|
||||
}
|
||||
}, 50);
|
||||
|
||||
setIsPlaying(false);
|
||||
|
||||
// Calculate initial progress
|
||||
const initialElapsed = startPos - startTime;
|
||||
const initialPercent = unlockedSeconds > 0 ? (initialElapsed / unlockedSeconds) * 100 : 0;
|
||||
setProgress(Math.min(initialPercent, 100));
|
||||
|
||||
setHasPlayedOnce(false); // Reset for new segment
|
||||
onHasPlayedChange?.(false); // Notify parent
|
||||
|
||||
// Update processed state
|
||||
setProcessedSrc(src);
|
||||
setProcessedUnlockedSeconds(unlockedSeconds);
|
||||
|
||||
if (autoPlay) {
|
||||
// Delay play slightly to ensure currentTime sticks
|
||||
setTimeout(() => {
|
||||
const playPromise = audioRef.current?.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise
|
||||
.then(() => {
|
||||
setIsPlaying(true);
|
||||
onPlay?.();
|
||||
setHasPlayedOnce(true);
|
||||
onHasPlayedChange?.(true); // Notify parent
|
||||
})
|
||||
.catch(error => {
|
||||
console.log("Autoplay prevented:", error);
|
||||
setIsPlaying(false);
|
||||
});
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [src, unlockedSeconds, startTime, autoPlay]);
|
||||
}, [src, unlockedSeconds, startTime, autoPlay, processedSrc, processedUnlockedSeconds]);
|
||||
|
||||
// Expose play method to parent component
|
||||
useImperativeHandle(ref, () => ({
|
||||
@@ -148,4 +190,6 @@ const AudioPlayer = forwardRef<AudioPlayerRef, AudioPlayerProps>(({ src, unlocke
|
||||
|
||||
AudioPlayer.displayName = 'AudioPlayer';
|
||||
|
||||
|
||||
|
||||
export default AudioPlayer;
|
||||
|
||||
Reference in New Issue
Block a user