Fix: Audio player skip behavior and range requests

This commit is contained in:
Hördle Bot
2025-11-26 10:58:04 +01:00
parent b66bab48bd
commit 301dce4c97
2 changed files with 119 additions and 39 deletions

View File

@@ -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;