Browse Source

Added SponsorBlock!

master
loicbersier 10 months ago
parent
commit
a3e24dd68a
3 changed files with 87 additions and 6 deletions
  1. +4
    -1
      README.md
  2. +76
    -5
      app/Controllers/Http/DownloadController.js
  3. +7
    -0
      resources/views/index.edge

+ 4
- 1
README.md View File

@ -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
МeiYali#2457 for CS translation

+ 76
- 5
app/Controllers/Http/DownloadController.js View File

@ -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}`)

+ 7
- 0
resources/views/index.edge View File

@ -83,6 +83,12 @@
<input class="checkbox" type="checkbox" name="feed" id="feed" title="Use this if you don't want the video you are downloading to be public">
{{ antl.formatMessage('messages.feed') }}
</label>
<label class="checkbox" for="sponsorBlock">
<input class="checkbox" type="checkbox" name="sponsorBlock" id="sponsorBlock" title="(Using sponsor.ajay.app)">
(W.I.P) Remove sponsors of video using <a href="https://sponsor.ajay.app/">SponsorBlock</a>
</label>
</div>
</div>
</div>
@ -213,6 +219,7 @@
</section>
@endif
<footer class="footer has-background-grey-dark has-text-light has-text-centered">
<p>Uses SponsorBlock API from <a href="https://sponsor.ajay.app/">https://sponsor.ajay.app/</a></p>
<p>{{ antl.formatMessage('messages.footer') }}</p>
@if(antl._locale == 'ar')
<bdi><p>{{ antl.formatMessage('messages.footer2p1') }} <a href="https://github.com/rg3/youtube-dl/">youtube-dl</a> - {{ antl.formatMessage('messages.footer2p2') }} <a href="https://discordapp.com/oauth2/authorize?client_id=377563711927484418&scope=bot&permissions=0">Haha yes</a> & <a href="https://twitter.com/ExplosmR">ExplosmRCG twitter bot</a> - {{ antl.formatMessage('messages.footer2p3') }}: {{ viewCounter }} - {{ antl.formatMessage('messages.footer2p4') }} <a href="https://discord.gg/cNRh5JQ">Supositware#1616</a> {{ antl.formatMessage('messages.footer2p5') }} </bdi></p>

Loading…
Cancel
Save