Skip to content

Commit ca64a77

Browse files
committed
Add SponsorBlock plugin
1 parent 30e94d1 commit ca64a77

File tree

5 files changed

+154
-1
lines changed

5 files changed

+154
-1
lines changed

config/defaults.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,19 @@ const defaultConfig = {
6363
volumeDown: "Shift+PageDown"
6464
},
6565
savedVolume: undefined //plugin save volume between session here
66-
}
66+
},
67+
sponsorblock: {
68+
enabled: false,
69+
apiURL: "https://sponsor.ajay.app",
70+
categories: [
71+
"sponsor",
72+
"intro",
73+
"outro",
74+
"interaction",
75+
"selfpromo",
76+
"music_offtopic",
77+
],
78+
},
6779
},
6880
};
6981

plugins/sponsorblock/back.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const fetch = require("node-fetch");
2+
3+
const defaultConfig = require("../../config/defaults");
4+
const registerCallback = require("../../providers/song-info");
5+
const { sortSegments } = require("./segments");
6+
7+
let videoID;
8+
9+
module.exports = (win, options) => {
10+
const { apiURL, categories } = {
11+
...defaultConfig.plugins.sponsorblock,
12+
...options,
13+
};
14+
15+
registerCallback(async (info) => {
16+
const newURL = info.url || win.webContents.getURL();
17+
const newVideoID = new URL(newURL).searchParams.get("v");
18+
19+
if (videoID !== newVideoID) {
20+
videoID = newVideoID;
21+
const segments = await fetchSegments(apiURL, categories);
22+
win.webContents.send("sponsorblock-skip", segments);
23+
}
24+
});
25+
};
26+
27+
const fetchSegments = async (apiURL, categories) => {
28+
const sponsorBlockURL = `${apiURL}/api/skipSegments?videoID=${videoID}&categories=${JSON.stringify(
29+
categories
30+
)}`;
31+
try {
32+
const resp = await fetch(sponsorBlockURL, {
33+
method: "GET",
34+
headers: {
35+
"Content-Type": "application/json",
36+
},
37+
redirect: "follow",
38+
});
39+
if (resp.status !== 200) {
40+
return [];
41+
}
42+
const segments = await resp.json();
43+
const sortedSegments = sortSegments(
44+
segments.map((submission) => submission.segment)
45+
);
46+
47+
return sortedSegments;
48+
} catch {
49+
return [];
50+
}
51+
};

plugins/sponsorblock/front.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const { ipcRenderer } = require("electron");
2+
3+
const is = require("electron-is");
4+
5+
const { ontimeupdate } = require("../../providers/video-element");
6+
7+
let currentSegments = [];
8+
9+
module.exports = () => {
10+
ipcRenderer.on("sponsorblock-skip", (_, segments) => {
11+
currentSegments = segments;
12+
});
13+
14+
ontimeupdate((videoElement) => {
15+
if (
16+
currentSegments.length > 0 &&
17+
videoElement.currentTime >= currentSegments[0][0] &&
18+
videoElement.currentTime <= currentSegments[0][1]
19+
) {
20+
videoElement.currentTime = currentSegments[0][1];
21+
const skipped = currentSegments.shift();
22+
if (is.dev()) {
23+
console.log("SponsorBlock: skipping segment", skipped);
24+
}
25+
}
26+
});
27+
};

plugins/sponsorblock/segments.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Segments are an array [ [start, end], … ]
2+
module.exports.sortSegments = (segments) => {
3+
segments.sort((segment1, segment2) =>
4+
segment1[0] === segment2[0]
5+
? segment1[1] - segment2[1]
6+
: segment1[0] - segment2[0]
7+
);
8+
9+
const compiledSegments = [];
10+
let currentSegment;
11+
12+
segments.forEach((segment) => {
13+
if (!currentSegment) {
14+
currentSegment = segment;
15+
return;
16+
}
17+
18+
if (currentSegment[1] < segment[0]) {
19+
compiledSegments.push(currentSegment);
20+
currentSegment = segment;
21+
return;
22+
}
23+
24+
currentSegment[1] = Math.max(currentSegment[1], segment[1]);
25+
});
26+
compiledSegments.push(currentSegment);
27+
28+
return compiledSegments;
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const { sortSegments } = require("../segments");
2+
3+
test("Segment sorting", () => {
4+
expect(
5+
sortSegments([
6+
[0, 3],
7+
[7, 8],
8+
[5, 6],
9+
])
10+
).toEqual([
11+
[0, 3],
12+
[5, 6],
13+
[7, 8],
14+
]);
15+
16+
expect(
17+
sortSegments([
18+
[0, 5],
19+
[6, 8],
20+
[4, 6],
21+
])
22+
).toEqual([[0, 8]]);
23+
24+
expect(
25+
sortSegments([
26+
[0, 6],
27+
[7, 8],
28+
[4, 6],
29+
])
30+
).toEqual([
31+
[0, 6],
32+
[7, 8],
33+
]);
34+
});

0 commit comments

Comments
 (0)