Current playback state after track change
Previous playback state before track change
Object containing the analysis results:
// Determine if a skip was manual or automatic
const manualAnalysis = detectManualVsAutoSkip(currentState, previousState);
console.log(
`Skip was ${manualAnalysis.isManual ? 'manual' : 'automatic'} ` +
`(${manualAnalysis.confidence.toFixed(2)} confidence): ${manualAnalysis.reason}`
);
export function detectManualVsAutoSkip(
state: PlaybackState,
previousState: PlaybackState,
): {
isManual: boolean;
confidence: number;
reason: string;
} {
// Default to manual with medium confidence
const result = {
isManual: true,
confidence: 0.6,
reason: "Default to manual assumption",
};
// If playback is stopped after track change, likely manual
if (!state.isPlaying && previousState.isPlaying) {
return {
isManual: true,
confidence: 0.9,
reason: "Playback stopped after track change, likely manual",
};
}
// If progress was almost at end, likely automatic
if (previousState.currentTrackDuration && previousState.lastProgress) {
const progressPercent =
previousState.lastProgress / previousState.currentTrackDuration;
if (progressPercent > 0.98) {
return {
isManual: false,
confidence: 0.95,
reason: "Track completed normally, automatic progression",
};
}
}
// Check for rapid skip pattern which indicates manual skipping
if (consecutiveQuickSkips >= AGGRESSIVE_SKIP_PATTERN_THRESHOLD) {
return {
isManual: true,
confidence: 0.95,
reason: `Part of rapid skip pattern (${consecutiveQuickSkips} consecutive)`,
};
}
// Return the default if no other condition met
return result;
}
Determines if a track change is likely a manual skip or automatic
Analyzes playback state transitions to determine if a track change was likely triggered manually by the user or automatically by the system. This distinction is important for understanding user intent versus normal playback progression.
The algorithm considers factors like: