-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpotifyLocalFilesFix.js
More file actions
116 lines (91 loc) · 2.99 KB
/
Copy pathSpotifyLocalFilesFix.js
File metadata and controls
116 lines (91 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// START METADATA
// NAME: Local Files Fixup
// AUTHOR: claude
// DESCRIPTION: Fixes Spotify's local file playback bug where tracks stop at 0:00.
// Root cause: Spotify's internal positionAsOfTimestamp desyncs when a
// local file auto-advances. A pause/play nudge doesn't fix this —
// we must force an explicit seekTo(0) to re-anchor the timestamp, then play.
// VERSION: 2.1.0
// END METADATA
(function LocalFilesFixup() {
if (
!Spicetify?.Player?.addEventListener ||
!Spicetify?.Platform?.PlayerAPI?.seekTo ||
!Spicetify?.Platform?.PlayerAPI?.resume
) {
setTimeout(LocalFilesFixup, 300);
return;
}
const INITIAL_DELAY_MS = 2000; // wait longer before checking
const MAX_ATTEMPTS = 2;
let attempts = 0;
let currentTrackUri = null;
let fixTimer = null;
function log(msg) {
console.log(`[LocalFilesFixup] ${msg}`);
}
function sleep(ms) {
return new Promise(r => setTimeout(r, ms));
}
function isLocal(item) {
const uri = item?.uri ?? item?.metadata?.uri ?? "";
return uri.startsWith("spotify:local:");
}
function getState() {
return Spicetify.Player.data ?? {};
}
function isStuck(state) {
const pos = state?.positionAsOfTimestamp ?? 0;
return !state?.isPaused && !!state?.isBuffering && pos === 0;
}
function scheduleCheck(delayMs) {
clearTimeout(fixTimer);
fixTimer = setTimeout(() => {
const state = getState();
const isSameTrack = state?.item?.uri === currentTrackUri;
if (!isSameTrack) return;
if (isStuck(state)) {
log("Track still stuck at 0:00");
applyFix();
} else {
log("Track is fine");
attempts = 0;
}
}, delayMs);
}
async function applyFix() {
const state = getState();
const uri = state?.item?.uri ?? "";
if (uri !== currentTrackUri) return;
attempts++;
log(`Fix attempt ${attempts}`);
try {
await Spicetify.Platform.PlayerAPI.seekTo(0);
await sleep(200);
if (getState()?.isPaused) {
await Spicetify.Platform.PlayerAPI.resume();
}
} catch (e) {
log("Fix error: " + e);
}
if (attempts >= MAX_ATTEMPTS) {
log("Giving up on track");
attempts = 0;
return;
}
scheduleCheck(800);
}
Spicetify.Player.addEventListener("songchange", (event) => {
clearTimeout(fixTimer);
attempts = 0;
const item = event?.data?.item ?? getState()?.item;
if (!isLocal(item)) {
currentTrackUri = null;
return;
}
currentTrackUri = item?.uri ?? null;
log(`Local file detected`);
scheduleCheck(INITIAL_DELAY_MS);
});
log("Loaded v7 - buffering-based detection");
})();