File size: 2,483 Bytes
0bafb27 | 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 | const crypto = require("crypto")
const axios = require("axios")
class savetube {
constructor() {
this.ky = 'C5D58EF67A7584E4A29F6C35BBC4EB12';
this.fmt = ['144', '240', '360', '480', '720', '1080', 'mp3'];
this.m = /^((?:https?:)?\/\/)?((?:www|m|music)\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(?:embed\/)?(?:v\/)?(?:shorts\/)?([a-zA-Z0-9_-]{11})/;
this.is = axios.create({
headers: {
'content-type': 'application/json',
'origin': 'https://yt.savetube.me',
'user-agent': 'Mozilla/5.0 (Android 15; Mobile; SM-F958; rv:130.0) Gecko/130.0 Firefox/130.0'
}
})
}
async decrypt(enc) {
try {
const [sr, ky] = [Buffer.from(enc,'base64'), Buffer.from(this.ky,'hex')]
const [iv, dt] = [sr.slice(0,16), sr.slice(16)]
const dc = crypto.createDecipheriv('aes-128-cbc', ky, iv);
return JSON.parse(Buffer.concat([dc.update(dt), dc.final()]).toString());
} catch (e) {
throw new Error(`Error while decrypting data: ${e.message}`);
}
}
async getCdn() {
const response = await this.is.get("https://media.savetube.vip/api/random-cdn");
if (!response.status) return response;
return {
status: true,
data: response.data.cdn
};
}
async download(url, format = 'mp3') {
const id = url.match(this.m)?.[3];
if (!id) {
return {
status: false,
msg: "ID cannot be extracted from url"
};
}
if (!format || !this.fmt.includes(format)) {
return {
status: false,
msg: "Formats not found",
list: this.fmt
};
}
try {
const u = await this.getCdn();
if (!u.status) return u;
const res = await this.is.post(`https://${u.data}/v2/info`, {
url: `https://www.youtube.com/watch?v=${id}`
});
const dec = await this.decrypt(res.data.data);
const dl = await this.is.post(`https://${u.data}/download`, {
id: id,
downloadType: format === 'mp3' ? 'audio' : 'video',
quality: format === 'mp3' ? '128' : format,
key: dec.key
})
return {
status: true,
title: dec.title,
format: format,
thumb: dec.thumbnail || `https://i.ytimg.com/vi/${id}/hqdefault.jpg`,
duration: dec.duration,
cached: dec.fromCache,
dl: dl.data.data.downloadUrl
};
} catch (error) {
return {
status: false,
error: error.message
};
}
} |