From 0563f9664f812e94b518a1381281270e41f4a3de Mon Sep 17 00:00:00 2001 From: nico Date: Mon, 2 Mar 2026 11:53:36 +0800 Subject: [PATCH] fix(musik): perbaiki timing dan rounding pada seek slider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Gunakan durasi dari database sebagai acuan utama (bukan dari audio metadata) - Ganti Math.floor dengan Math.round untuk smoothing currentTime - Tambahkan validasi seek time: Math.min(Math.max(0, v), duration) - Tambahkan debug logging untuk tracking seek behavior - Hapus override duration di onLoadedMetadata untuk menghindari konflik Root cause: - Duration dari database (string 'MM:SS' → seconds) berbeda dengan audio.duration (float) - Math.floor menyebabkan lompatan kasar dan kehilangan presisi - onLoadedMetadata override duration dengan audio.duration yang tidak exact Fix: - Database duration = source of truth - Math.round untuk smoothing tanpa kehilangan presisi - Validasi bounds untuk mencegah seek negatif atau melebihi durasi Co-authored-by: Qwen-Coder --- src/app/darmasaba/(pages)/musik/lib/seek.ts | 6 ++++- .../(pages)/musik/musik-desa/page.tsx | 27 +++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/app/darmasaba/(pages)/musik/lib/seek.ts b/src/app/darmasaba/(pages)/musik/lib/seek.ts index 25184919..68338f23 100644 --- a/src/app/darmasaba/(pages)/musik/lib/seek.ts +++ b/src/app/darmasaba/(pages)/musik/lib/seek.ts @@ -5,10 +5,14 @@ export function seekTo( ) { if (!audioRef.current) return; + // Set waktu audio audioRef.current.currentTime = time; // Update state jika provided if (setCurrentTime) { - setCurrentTime(time); + setCurrentTime(Math.round(time)); } + + // Debug log (bisa dihapus nanti) + console.log('[seekTo] Seek to:', time, 'seconds'); } diff --git a/src/app/darmasaba/(pages)/musik/musik-desa/page.tsx b/src/app/darmasaba/(pages)/musik/musik-desa/page.tsx index 6fedfe87..76e629ce 100644 --- a/src/app/darmasaba/(pages)/musik/musik-desa/page.tsx +++ b/src/app/darmasaba/(pages)/musik/musik-desa/page.tsx @@ -103,6 +103,7 @@ const MusicPlayer = () => { // Update duration when song changes useEffect(() => { if (currentSong && audioRef.current) { + // Gunakan durasi dari database sebagai acuan utama const durationParts = currentSong.durasi.split(':'); const durationInSeconds = parseInt(durationParts[0]) * 60 + parseInt(durationParts[1]); setDuration(durationInSeconds); @@ -199,12 +200,22 @@ const MusicPlayer = () => { src={currentSong.audioFile.link} muted={isMuted} onLoadedMetadata={() => { - if (!audioRef.current) return; - setDuration(Math.floor(audioRef.current.duration)); + // Jangan override duration dari database + // Audio element duration bisa berbeda beberapa ms + if (audioRef.current) { + audioRef.current.currentTime = 0; + } }} onTimeUpdate={() => { if (!audioRef.current || isSeeking) return; - setCurrentTime(Math.floor(audioRef.current.currentTime)); + // Gunakan pembulatan yang lebih smooth + const time = audioRef.current.currentTime; + const roundedTime = Math.round(time); + // Debug: log jika ada perbedaan besar antara time dan state + if (Math.abs(time - roundedTime) > 0.5) { + console.log('[onTimeUpdate] Time:', time, 'Rounded:', roundedTime); + } + setCurrentTime(roundedTime); }} onEnded={handleSongEnd} /> @@ -269,7 +280,10 @@ const MusicPlayer = () => { }} onChangeEnd={(v) => { setIsSeeking(false); - seekTo(audioRef, v, setCurrentTime); + // Validasi: jangan seek melebihi durasi + const seekTime = Math.min(Math.max(0, v), duration); + seekTo(audioRef, seekTime, setCurrentTime); + console.log('[Slider Atas] Seek end:', seekTime, 'Duration:', duration); }} color="#0B4F78" size="sm" @@ -411,7 +425,10 @@ const MusicPlayer = () => { }} onChangeEnd={(v) => { setIsSeeking(false); - seekTo(audioRef, v); // commit - update audio player + // Validasi: jangan seek melebihi durasi + const seekTime = Math.min(Math.max(0, v), duration); + seekTo(audioRef, seekTime, setCurrentTime); + console.log('[Slider Bawah] Seek end:', seekTime, 'Duration:', duration); }} color="#0B4F78" size="xs"