pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

remove "smart" skip detection

It really wasnt smart. Just report the skip time from the APIs

Pas 445fd373 4024aecd

+6 -85
+4 -83
src/components/player/hooks/useSkipTracking.ts
··· 29 29 } 30 30 31 31 /** 32 - * Calculate confidence score for automatic skip detection 33 - * Based on skip duration and timing within the video 34 - */ 35 - function calculateSkipConfidence( 36 - skipDuration: number, 37 - startTime: number, 38 - duration: number, 39 - ): number { 40 - // Duration confidence: longer skips are more confident 41 - // 20s = 0.4, 40s = 0.6, 60s+ = 0.85 42 - const durationConfidence = Math.min(0.85, 0.4 + (skipDuration - 20) * 0.01); 43 - 44 - // Timing confidence: earlier skips are more confident 45 - // Start time as percentage of total duration 46 - const startPercentage = startTime / duration; 47 - // Higher confidence for earlier starts (0% = 1.0, 20% = 0.8) 48 - const timingConfidence = Math.max(0.7, 1.0 - startPercentage * 0.75); 49 - 50 - // Combine factors (weighted average) 51 - return durationConfidence * 0.6 + timingConfidence * 0.4; 52 - } 53 - 54 - /** 55 - * Hook that tracks rapid skipping sessions where users accumulate 20+ seconds of forward 56 - * movement within a 5-second window. Sessions continue until 8 seconds pass without 57 - * any forward movement, then report the total skip distance. Ignores skips that start 58 - * after 20% of video duration (unlikely to be intro skipping). 32 + * Hook that tracks manual skip events and monitors user behavior patterns for confidence adjustment. 33 + * Only processes skip events added via addSkipEvent (e.g., from skip intro button). 59 34 * 60 35 * @param minSkipThreshold Minimum total forward movement in 5-second window to start session (default: 20) 61 36 * @param maxHistory Maximum number of skip events to keep in history (default: 50) ··· 74 49 // Get current player state 75 50 const progress = usePlayerStore((s) => s.progress); 76 51 const meta = usePlayerStore((s) => s.meta); 77 - const duration = progress.duration; 78 52 79 53 const clearHistory = useCallback(() => { 80 54 setSkipHistory([]); ··· 149 123 ); 150 124 151 125 if (isInSkipSessionRef.current && recentEntries.length === 0) { 152 - // Ignore skips that start after 20% of video duration (likely not intro skipping) 153 - const twentyPercentMark = duration * 0.2; 154 - if (skipSessionStartRef.current > twentyPercentMark) { 155 - // Reset session state without creating event 156 - isInSkipSessionRef.current = false; 157 - skipSessionStartRef.current = 0; 158 - sessionTotalRef.current = 0; 159 - skipWindowRef.current = []; 160 - return; 161 - } 162 - 163 - // Only report skips where end time is greater than start time 164 - if (currentTime <= skipSessionStartRef.current) { 165 - // Reset session state without creating event 166 - isInSkipSessionRef.current = false; 167 - skipSessionStartRef.current = 0; 168 - sessionTotalRef.current = 0; 169 - skipWindowRef.current = []; 170 - return; 171 - } 172 - 173 - // Create skip event for completed session 174 - const skipEvent: SkipEvent = { 175 - startTime: skipSessionStartRef.current, 176 - endTime: currentTime, 177 - skipDuration: sessionTotalRef.current, 178 - timestamp: now, 179 - confidence: calculateSkipConfidence( 180 - sessionTotalRef.current, 181 - skipSessionStartRef.current, 182 - duration, 183 - ), 184 - meta: meta 185 - ? { 186 - title: 187 - meta.type === "show" && meta.episode 188 - ? `${meta.title} - S${meta.season?.number || 0}E${meta.episode.number || 0}` 189 - : meta.title, 190 - type: meta.type === "movie" ? "Movie" : "TV Show", 191 - tmdbId: meta.tmdbId, 192 - seasonNumber: meta.season?.number, 193 - episodeNumber: meta.episode?.number, 194 - } 195 - : undefined, 196 - }; 197 - 198 - setSkipHistory((prev) => { 199 - const newHistory = [...prev, skipEvent]; 200 - return newHistory.length > maxHistory 201 - ? newHistory.slice(newHistory.length - maxHistory) 202 - : newHistory; 203 - }); 204 - 205 - // Reset session state 126 + // Session ended - reset state but DON'T create skip event 206 127 isInSkipSessionRef.current = false; 207 128 skipSessionStartRef.current = 0; 208 129 sessionTotalRef.current = 0; ··· 210 131 } 211 132 212 133 previousTimeRef.current = currentTime; 213 - }, [progress.time, duration, meta, minSkipThreshold, maxHistory]); 134 + }, [progress.time, minSkipThreshold]); 214 135 215 136 useEffect(() => { 216 137 // Monitor time changes every 100ms to catch rapid skipping
+2 -2
src/components/player/internals/Backend/SkipTracker.tsx
··· 82 82 return { 83 83 skip, 84 84 originalConfidence: skip.confidence, 85 - startTime: progress.time, 85 + startTime: skip.startTime, 86 86 endTime: skip.endTime, 87 87 hasBackwardMovement: false, 88 88 timer, 89 89 }; 90 90 }, 91 - [progress.time, sendSkipAnalytics], 91 + [sendSkipAnalytics], 92 92 ); 93 93 94 94 useEffect(() => {