diff --git a/lib/hooks/useMultiTrackPlayer.ts b/lib/hooks/useMultiTrackPlayer.ts index 836b92a..1226691 100644 --- a/lib/hooks/useMultiTrackPlayer.ts +++ b/lib/hooks/useMultiTrackPlayer.ts @@ -32,6 +32,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { const pausedAtRef = useRef(0); const animationFrameRef = useRef(null); const levelMonitorFrameRef = useRef(null); + const isMonitoringLevelsRef = useRef(false); const tracksRef = useRef(tracks); // Always keep latest tracks // Keep tracksRef in sync with tracks prop @@ -52,7 +53,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { // Monitor playback levels for all tracks const monitorPlaybackLevels = useCallback(() => { - if (!isPlaying || analyserNodesRef.current.length === 0) return; + if (!isMonitoringLevelsRef.current || analyserNodesRef.current.length === 0) return; const levels: Record = {}; @@ -75,10 +76,8 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { setTrackLevels(levels); - if (isPlaying) { - levelMonitorFrameRef.current = requestAnimationFrame(monitorPlaybackLevels); - } - }, [isPlaying]); + levelMonitorFrameRef.current = requestAnimationFrame(monitorPlaybackLevels); + }, []); const updatePlaybackPosition = useCallback(() => { if (!audioContextRef.current) return; @@ -88,12 +87,18 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { if (newTime >= duration) { setIsPlaying(false); + isMonitoringLevelsRef.current = false; setCurrentTime(0); pausedAtRef.current = 0; + setTrackLevels({}); if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); animationFrameRef.current = null; } + if (levelMonitorFrameRef.current) { + cancelAnimationFrame(levelMonitorFrameRef.current); + levelMonitorFrameRef.current = null; + } return; } @@ -185,8 +190,10 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { source.onended = () => { if (pausedAtRef.current + (audioContext.currentTime - startTimeRef.current) >= duration) { setIsPlaying(false); + isMonitoringLevelsRef.current = false; setCurrentTime(0); pausedAtRef.current = 0; + setTrackLevels({}); } }; } @@ -194,6 +201,9 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { startTimeRef.current = audioContext.currentTime; setIsPlaying(true); updatePlaybackPosition(); + + // Start level monitoring + isMonitoringLevelsRef.current = true; monitorPlaybackLevels(); }, [tracks, duration, masterVolume, updatePlaybackPosition, monitorPlaybackLevels]); @@ -217,6 +227,9 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { setIsPlaying(false); + // Stop level monitoring + isMonitoringLevelsRef.current = false; + if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); animationFrameRef.current = null; @@ -421,8 +434,10 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { source.onended = () => { if (pausedAtRef.current + (audioContext.currentTime - startTimeRef.current) >= duration) { setIsPlaying(false); + isMonitoringLevelsRef.current = false; setCurrentTime(0); pausedAtRef.current = 0; + setTrackLevels({}); } }; } @@ -430,6 +445,9 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { startTimeRef.current = audioContext.currentTime; setIsPlaying(true); + // Start level monitoring + isMonitoringLevelsRef.current = true; + // Start animation frame for position updates const updatePosition = () => { if (!audioContextRef.current) return; @@ -439,12 +457,17 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { if (newTime >= duration) { setIsPlaying(false); + isMonitoringLevelsRef.current = false; setCurrentTime(0); pausedAtRef.current = 0; if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); animationFrameRef.current = null; } + if (levelMonitorFrameRef.current) { + cancelAnimationFrame(levelMonitorFrameRef.current); + levelMonitorFrameRef.current = null; + } return; } @@ -513,6 +536,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { // Cleanup on unmount useEffect(() => { return () => { + isMonitoringLevelsRef.current = false; if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); }