UNPKG

@tiktikimelbo7/extensions

Version:

Nodejs library that provides high-level APIs for obtaining information on various entertainment media such as books, movies, comic books, anime, manga, and so on.

174 lines 8.32 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const cheerio_1 = require("cheerio"); const crypto_js_1 = __importDefault(require("crypto-js")); const utils_1 = require("../utils"); const models_1 = require("../models"); class RapidCloud extends models_1.VideoExtractor { constructor() { super(...arguments); this.serverName = 'RapidCloud'; this.sources = []; this.fallbackKey = 'c1d17096f2ca11b7'; this.host = 'https://rapid-cloud.co'; this.consumetApi = 'https://api.consumet.org'; this.enimeApi = 'https://api.enime.moe'; this.extract = async (videoUrl) => { var _a, _b; const result = { sources: [], subtitles: [], }; try { const id = (_a = videoUrl.href.split('/').pop()) === null || _a === void 0 ? void 0 : _a.split('?')[0]; const options = { headers: { 'X-Requested-With': 'XMLHttpRequest', }, }; let res = null; // let { data: sId } = await this.client({ // method: 'GET', // url: `${this.consumetApi}/utils/rapid-cloud`, // validateStatus: status => true, // }); // if (!sId) { // sId = await this.client({ // method: 'GET', // url: `${this.enimeApi}/tool/rapid-cloud/server-id`, // validateStatus: status => true, // }); // } res = await this.client.get(`https://${videoUrl.hostname}/embed-2/ajax/e-1/getSources?id=${id}`, options); let { data: { sources, tracks, intro, encrypted }, } = res; let decryptKey = await (await this.client.get('https://github.com/enimax-anime/key/blob/e6/key.txt')).data; decryptKey = (0, utils_1.substringBefore)((0, utils_1.substringAfter)(decryptKey, '"blob-code blob-code-inner js-file-line">'), '</td>'); if (!decryptKey) { decryptKey = await (await this.client.get('https://raw.githubusercontent.com/enimax-anime/key/e6/key.txt')).data; } if (!decryptKey) decryptKey = this.fallbackKey; try { if (encrypted) { const sourcesArray = sources.split(""); let extractedKey = ""; for (const index of decryptKey) { for (let i = index[0]; i < index[1]; i++) { extractedKey += sources[i]; sourcesArray[i] = ""; } } decryptKey = extractedKey; sources = sourcesArray.join(""); const decrypt = crypto_js_1.default.AES.decrypt(sources, decryptKey); sources = JSON.parse(decrypt.toString(crypto_js_1.default.enc.Utf8)); } } catch (err) { throw new Error('Cannot decrypt sources. Perhaps the key is invalid.'); } this.sources = sources === null || sources === void 0 ? void 0 : sources.map((s) => ({ url: s.file, isM3U8: s.file.includes('.m3u8'), })); result.sources.push(...this.sources); if (videoUrl.href.includes(new URL(this.host).host)) { result.sources = []; this.sources = []; for (const source of sources) { const { data } = await this.client.get(source.file, options); const m3u8data = data .split('\n') .filter((line) => line.includes('.m3u8') && line.includes('RESOLUTION=')); const secondHalf = m3u8data.map((line) => { var _a; return (_a = line.match(/RESOLUTION=.*,(C)|URI=.*/g)) === null || _a === void 0 ? void 0 : _a.map((s) => s.split('=')[1]); }); const TdArray = secondHalf.map((s) => { const f1 = s[0].split(',C')[0]; const f2 = s[1].replace(/"/g, ''); return [f1, f2]; }); for (const [f1, f2] of TdArray) { this.sources.push({ url: `${(_b = source.file) === null || _b === void 0 ? void 0 : _b.split('master.m3u8')[0]}${f2.replace('iframes', 'index')}`, quality: f1.split('x')[1] + 'p', isM3U8: f2.includes('.m3u8'), }); } result.sources.push(...this.sources); } if (intro.end > 1) { result.intro = { start: intro.start, end: intro.end, }; } } result.sources.push({ url: sources[0].file, isM3U8: sources[0].file.includes('.m3u8'), quality: 'auto', }); result.subtitles = tracks .map((s) => s.file ? { url: s.file, lang: s.label ? s.label : 'Thumbnails', } : null) .filter((s) => s); return result; } catch (err) { throw err; } }; this.captcha = async (url, key) => { const uri = new URL(url); const domain = uri.protocol + '//' + uri.host; const { data } = await this.client.get(`https://www.google.com/recaptcha/api.js?render=${key}`, { headers: { Referer: domain, }, }); const v = data === null || data === void 0 ? void 0 : data.substring(data.indexOf('/releases/'), data.lastIndexOf('/recaptcha')).split('/releases/')[1]; //TODO: NEED to fix the co (domain) parameter to work with every domain const anchor = `https://www.google.com/recaptcha/api2/anchor?ar=1&hl=en&size=invisible&cb=kr42069kr&k=${key}&co=aHR0cHM6Ly9yYXBpZC1jbG91ZC5ydTo0NDM.&v=${v}`; const c = (0, cheerio_1.load)((await this.client.get(anchor)).data)('#recaptcha-token').attr('value'); // currently its not returning proper response. not sure why const res = await this.client.post(`https://www.google.com/recaptcha/api2/reload?k=${key}`, { v: v, k: key, c: c, co: 'aHR0cHM6Ly9yYXBpZC1jbG91ZC5ydTo0NDM.', sa: '', reason: 'q', }, { headers: { Referer: anchor, }, }); return res.data.substring(res.data.indexOf('rresp","'), res.data.lastIndexOf('",null')); }; // private wss = async (): Promise<string> => { // let sId = ''; // const ws = new WebSocket('wss://ws1.rapid-cloud.ru/socket.io/?EIO=4&transport=websocket'); // ws.on('open', () => { // ws.send('40'); // }); // return await new Promise((resolve, reject) => { // ws.on('message', (data: string) => { // data = data.toString(); // if (data?.startsWith('40')) { // sId = JSON.parse(data.split('40')[1]).sid; // ws.close(4969, "I'm a teapot"); // resolve(sId); // } // }); // }); // }; } } exports.default = RapidCloud; //# sourceMappingURL=rapidcloud.js.map