diff --git a/README.md b/README.md
index 3be1f38..89ff1ba 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,9 @@ Jeff downloader is a website to download from [hundreds](https://ytdl-org.github
You can find a hosted version on https://namejeff.xyz/
# Credit
+
+SponsorBlock data is used under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). More details: https://sponsor.ajay.app/
+
[Youtube-dl](https://github.com/ytdl-org/youtube-dl/)
Major Tom#6196 for AR translation
@@ -13,4 +16,4 @@ Major Tom#6196 for AR translation
Mastah Gengu#1596 for DE translation
-МeiYali#2457 for CS translation
\ No newline at end of file
+МeiYali#2457 for CS translation
diff --git a/app/Controllers/Http/DownloadController.js b/app/Controllers/Http/DownloadController.js
index 2da8355..404a543 100644
--- a/app/Controllers/Http/DownloadController.js
+++ b/app/Controllers/Http/DownloadController.js
@@ -5,7 +5,8 @@ const path = require('path');
const ffmpeg = require('fluent-ffmpeg');
const { version } = require('../../../package.json');
const Antl = use('Antl');
-const proxy = require('../../../proxy/proxy.json')
+const proxy = require('../../../proxy/proxy.json');
+const fetch = require('node-fetch');
let viewCounter = 0;
let files = [];
@@ -104,7 +105,8 @@ class DownloadController {
format: request.input('format'),
alt: request.input('alt'),
feed: request.input('feed'),
- proxy: request.input('proxy')
+ proxy: request.input('proxy'),
+ sponsorBlock : request.input('sponsorBlock')
}
if (!data.url) {
@@ -114,6 +116,19 @@ class DownloadController {
return view.render(page, viewOption);
}
+ let videoID;
+ if (data.sponsorBlock) {
+ let regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
+ let match = data.url.match(regExp);
+ videoID = (match&&match[7].length==11)? match[7] : false;
+ if (!videoID) {
+ let viewOption = {...defaultViewOption};
+ viewOption.error = true;
+ viewOption.errormsg = 'To use sponsorBlock you need a valid youtube link!';
+ return view.render(page, viewOption);
+ }
+ }
+
// Youtube-dl quality settings
if (data.quality == 'small')
option = 'worst'
@@ -177,6 +192,7 @@ class DownloadController {
let title = info.title.slice(0,50);
DLFile = `${title.replace(/\s/g, '')}.${ext}`;
DLFile = DLFile.replace(/[()]|[/]|[\\]|[!]|[?]/g, '');
+ DLFile = DLFile.replace(',', '');
// If no title use the ID
if (title == '_') title = `_${info.id}`;
@@ -189,9 +205,64 @@ class DownloadController {
video.on('end', function() {
if (data.format == 'mp4' || data.format == 'webm') {
- // If user requested mp4 directly attach the file
- generateThumbnail(DLFile);
- return response.attachment(`./public/uploads/${DLFile}`)
+ if (data.sponsorBlock) { // WARNING: THIS PART SUCK
+ let filter = '';
+ let abc = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
+ fetch(`https://sponsor.ajay.app/api/skipSegments?videoID=${videoID}`)
+ .then(res => res.json())
+ .then(json => {
+ let i = 0;
+ let previousEnd;
+ let usedLetter = [];
+
+ json.forEach(sponsor => {
+ usedLetter.push(abc[i]);
+ if (i === 0) {
+ filter += `[0:v]trim=start=0:end=${sponsor.segment[0]},setpts=PTS-STARTPTS[${abc[i]}v];`;
+ filter += `[0:a]atrim=start=0:end=${sponsor.segment[0]},asetpts=PTS-STARTPTS[${abc[i]}a];`;
+ } else {
+ filter += `[0:v]trim=start=${previousEnd}:end=${sponsor.segment[0]},setpts=PTS-STARTPTS[${abc[i]}v];`;
+ filter += `[0:a]atrim=start=${previousEnd}:end=${sponsor.segment[0]},asetpts=PTS-STARTPTS[${abc[i]}a];`;
+ }
+ previousEnd = sponsor.segment[1];
+ i++;
+ });
+ usedLetter.push(abc[i]);
+ filter += `[0:v]trim=start=${previousEnd},setpts=PTS-STARTPTS[${abc[i]}v];`;
+ filter += `[0:a]atrim=start=${previousEnd},asetpts=PTS-STARTPTS[${abc[i]}a];`;
+ let video = '';
+ let audio = '';
+ usedLetter.forEach(letter => {
+ video += `[${letter}v]`
+ audio += `[${letter}a]`
+ });
+ filter += `${video}concat=n=${i + 1}[outv];`;
+ filter += `${audio}concat=n=${i + 1}:v=0:a=1[outa]`;
+
+ ffmpeg(`./public/uploads/${DLFile}`)
+ .inputFormat('mp4')
+ .complexFilter(filter)
+ .outputOptions('-map [outv]')
+ .outputOptions('-map [outa]')
+ .save(`./public/uploads/hidden/nosponsor${DLFile}`)
+ .on('error', function(err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ console.log('Cannot process video: ' + err.message);
+ return;
+ })
+ .on('end', () => {
+ console.log('end');
+ fs.renameSync(`./public/uploads/hidden/nosponsor${DLFile}`, `./public/uploads/${DLFile}`)
+ response.attachment(`./public/uploads/${DLFile}`)
+ generateThumbnail(DLFile);
+ });
+ });
+ } else {
+ // If user requested mp4 directly attach the file
+ response.attachment(`./public/uploads/${DLFile}`)
+ generateThumbnail(DLFile);
+ }
} else {
// If user requested an audio format, convert it
ffmpeg(`./public/uploads/${DLFile}`)
diff --git a/resources/views/index.edge b/resources/views/index.edge
index b6c6c73..3963d86 100644
--- a/resources/views/index.edge
+++ b/resources/views/index.edge
@@ -83,6 +83,12 @@
{{ antl.formatMessage('messages.feed') }}
+
+
+
@@ -213,6 +219,7 @@
@endif