diff --git a/jam-ui/src/components/client/JKSessionBackingTrackPlayer.js b/jam-ui/src/components/client/JKSessionBackingTrackPlayer.js index ff7c3f3ce..13ecf6fe7 100644 --- a/jam-ui/src/components/client/JKSessionBackingTrackPlayer.js +++ b/jam-ui/src/components/client/JKSessionBackingTrackPlayer.js @@ -132,12 +132,11 @@ const JKSessionBackingTrackPlayer = ({ const handlePlay = async () => { try { - console.log('[BTP-UAT003] handlePlay:', { + console.log('[BTP] handlePlay:', { isPlaying, currentPositionMs, durationMs, - hasPendingSeek: pendingSeekPositionRef.current !== null, - pendingSeekPosition: pendingSeekPositionRef.current + hasPendingSeek: pendingSeekPositionRef.current !== null }); if (isPlaying) { @@ -146,16 +145,13 @@ const JKSessionBackingTrackPlayer = ({ setIsPlaying(false); console.log('[BTP] Paused'); } else { - // UAT-003 Investigation Approach 2: Apply pending seek position before resuming + // UAT-003 Fix: Apply pending seek position before resuming if (pendingSeekPositionRef.current !== null) { - console.log('[BTP-UAT003] Applying pending seek position before play:', pendingSeekPositionRef.current); + console.log('[BTP] Applying pending seek position:', pendingSeekPositionRef.current); - // Try stopping first, then seeking, then playing + // Stop, seek, then play await jamClient.SessionStopPlay(); - console.log('[BTP-UAT003] Stop completed for pending seek'); - await jamClient.SessionTrackSeekMs(pendingSeekPositionRef.current); - console.log('[BTP-UAT003] Seek to pending position completed'); // Update UI state setCurrentPositionMs(pendingSeekPositionRef.current); @@ -268,22 +264,17 @@ const JKSessionBackingTrackPlayer = ({ }; /* - * UAT-003 Investigation: Seek while paused limitation + * UAT-003 Fix: Seek while paused limitation workaround * - * Problem: When track is paused and user drags slider to new position, the seek doesn't - * register with jamClient. On resume, audio plays from old position. + * Problem: jamClient.SessionTrackSeekMs() doesn't register when track is paused. * - * Approaches tested: - * 1. Verify position after SessionTrackSeekMs() call - confirms seek doesn't take effect when paused - * 2. State machine approach - store pending seek position, apply before resume with: - * - SessionStopPlay() to reset state - * - SessionTrackSeekMs() to seek to stored position - * - SessionStartPlay() to resume playback + * Solution: State machine approach + * - When seeking while paused, verify if position changed + * - If not, store pending seek position in pendingSeekPositionRef + * - Before resuming playback, apply pending seek with: + * SessionStopPlay() → SessionTrackSeekMs() → SessionStartPlay() * - * This implementation combines both approaches: - * - Diagnostic logging to confirm the issue - * - Pending seek position stored in pendingSeekPositionRef - * - Applied in handlePlay() before resuming playback + * This provides consistent UX: seek works whether playing or paused. * * See: .planning/phases/02-backing-track-seek-controls/02-01-ISSUES.md (UAT-003) */ @@ -291,47 +282,30 @@ const JKSessionBackingTrackPlayer = ({ const seekPositionMs = parseInt(e.target.value); try { - console.log('[BTP-UAT003] handleSeek BEFORE:', { - seekPositionMs, - durationMs, - isPlaying, - currentPositionMs, - isPaused: !isPlaying - }); + console.log('[BTP] handleSeek:', { seekPositionMs, isPlaying }); // Update local state immediately for responsive UI setCurrentPositionMs(seekPositionMs); setCurrentTime(formatTime(seekPositionMs)); - // UAT-003 Investigation: Check if track is playing before seek - const trackIsPlayingBefore = await jamClient.isSessionTrackPlaying(); - console.log('[BTP-UAT003] Track playing state before seek:', trackIsPlayingBefore); - // Seek the native client to the new position await jamClient.SessionTrackSeekMs(seekPositionMs); - console.log('[BTP-UAT003] SessionTrackSeekMs called with:', seekPositionMs); - // UAT-003 Investigation: Verify position after seek + // UAT-003: Verify position after seek (especially when paused) const positionAfterSeek = await jamClient.SessionCurrrentPlayPosMs(); const parsedPosition = parseInt(positionAfterSeek, 10) || 0; - console.log('[BTP-UAT003] Position after seek:', { - returned: positionAfterSeek, - parsed: parsedPosition, - expected: seekPositionMs, - matched: parsedPosition === seekPositionMs - }); - // UAT-003 Investigation Approach 1: If paused and position didn't change, store for later + // If paused and position didn't change, store for application on resume if (!isPlaying && parsedPosition !== seekPositionMs) { - console.warn('[BTP-UAT003] Seek while paused did not take effect. Storing pending position.'); + console.log('[BTP] Seek while paused - storing pending position:', seekPositionMs); pendingSeekPositionRef.current = seekPositionMs; } else { pendingSeekPositionRef.current = null; } - console.log('[BTP-UAT003] Seek completed'); + console.log('[BTP] Seek completed'); } catch (error) { - console.error('[BTP-UAT003] Error seeking:', error); + console.error('[BTP] Error seeking:', error); } };