fix(03-03): verify playback state and add loop diagnostics

Race condition fix:
- After SessionStartPlay, verify actual playback state
- Add 100ms delay to let native client update
- Check isSessionTrackPlaying() before setting state
- Prevents "double click" issue where component thinks it's playing but isn't

Loop diagnostics:
- Add [LOOP] logging to track loop changes
- Add [POLLING] logging when track reaches end
- Log whether loop is enabled and native client behavior
- Help diagnose why loop not repeating

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-01-14 19:30:42 +05:30
parent ac4dcea21e
commit 9d9fd86c04
1 changed files with 16 additions and 2 deletions

View File

@ -181,8 +181,10 @@ const JKSessionBackingTrackPlayer = ({
// Check if track reached the end
if (validPosition >= validDuration && validDuration > 0) {
console.log('[POLLING] Track reached end, isLooping:', isLooping);
// If loop is enabled, don't interfere - let native client handle loop
if (!isLooping) {
console.log('[POLLING] Not looping, stopping and resetting');
// Stop playback and reset to beginning for clean state
await jamClient.SessionStopPlay();
setIsPlaying(false);
@ -193,6 +195,7 @@ const JKSessionBackingTrackPlayer = ({
return;
}
// If looping, just continue polling - native client will loop
console.log('[POLLING] Looping enabled, letting native client handle loop');
}
// Only update state if values actually changed (lazy updates)
@ -307,8 +310,14 @@ const JKSessionBackingTrackPlayer = ({
// Play (1 = normal playback mode)
console.log('[PLAY] Calling SessionStartPlay');
await jamClient.SessionStartPlay(1);
setIsPlaying(true);
console.log('[PLAY] Playback started successfully');
// Verify playback actually started (small delay to let native client update)
await new Promise(resolve => setTimeout(resolve, 100));
const actuallyPlaying = await jamClient.isSessionTrackPlaying();
console.log('[PLAY] After SessionStartPlay, actuallyPlaying:', actuallyPlaying);
setIsPlaying(actuallyPlaying);
console.log('[PLAY] Playback started, state set to:', actuallyPlaying);
}
} catch (error) {
handleError('playback', 'Failed to start playback', error);
@ -408,6 +417,7 @@ const JKSessionBackingTrackPlayer = ({
const handleLoopChange = useCallback(async (e) => {
const shouldLoop = e.target.checked;
const previousLoop = isLooping;
console.log('[LOOP] Loop change requested:', shouldLoop);
setIsLooping(shouldLoop);
try {
@ -420,14 +430,18 @@ const JKSessionBackingTrackPlayer = ({
// Set loop state using SessionSetBackingTrackFileLoop
// This requires the file path and loop boolean
const trackPath = getBackingTrackPath(backingTrack);
console.log('[LOOP] Track path:', trackPath);
if (!trackPath) {
handleError('playback', 'No backing track available for loop change', null);
setIsLooping(previousLoop); // Revert checkbox
return;
}
console.log('[LOOP] Calling SessionSetBackingTrackFileLoop with path:', trackPath, 'shouldLoop:', shouldLoop);
await jamClient.SessionSetBackingTrackFileLoop(trackPath, shouldLoop);
console.log('[LOOP] Loop set successfully');
} catch (error) {
console.error('[LOOP] Failed to set loop:', error);
handleError('playback', 'Failed to toggle loop', error);
setIsLooping(previousLoop); // Revert checkbox on error
}