mirror of
https://git.luna-app.eu/50n50/sources
synced 2025-12-21 21:26:19 +01:00
Updated GlobalExtractor version to 1.1.8
This commit is contained in:
parent
9e589f3dc4
commit
2ff8f723ff
22 changed files with 6419 additions and 253 deletions
|
|
@ -147,7 +147,7 @@ function cleanHtmlSymbols(string) {
|
|||
// EDITING THIS FILE COULD BREAK THE UPDATER AND CAUSE ISSUES WITH THE EXTRACTOR
|
||||
|
||||
/* {GE START} */
|
||||
/* {VERSION: 1.1.4} */
|
||||
/* {VERSION: 1.1.8} */
|
||||
|
||||
/**
|
||||
* @name global_extractor.js
|
||||
|
|
@ -155,12 +155,13 @@ function cleanHtmlSymbols(string) {
|
|||
* @author Cufiy
|
||||
* @url https://github.com/JMcrafter26/sora-global-extractor
|
||||
* @license CUSTOM LICENSE - see https://github.com/JMcrafter26/sora-global-extractor/blob/main/LICENSE
|
||||
* @date 2025-08-13 03:44:07
|
||||
* @version 1.1.4
|
||||
* @date 2025-11-05 15:44:57
|
||||
* @version 1.1.8
|
||||
* @note This file was generated automatically.
|
||||
* The global extractor comes with an auto-updating feature, so you can always get the latest version. https://github.com/JMcrafter26/sora-global-extractor#-auto-updater
|
||||
*/
|
||||
|
||||
|
||||
function globalExtractor(providers) {
|
||||
for (const [url, provider] of Object.entries(providers)) {
|
||||
try {
|
||||
|
|
@ -307,6 +308,8 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
headers["encoding"] = "windows-1251"; // required
|
||||
} else if (provider == 'sibnet') {
|
||||
headers["encoding"] = "windows-1251"; // required
|
||||
} else if (provider == 'supervideo') {
|
||||
delete headers["User-Agent"];
|
||||
}
|
||||
|
||||
// fetch the url
|
||||
|
|
@ -367,6 +370,13 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
console.log("Error extracting stream URL from doodstream:", error);
|
||||
return null;
|
||||
}
|
||||
case "earnvids":
|
||||
try {
|
||||
return await earnvidsExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from earnvids:", error);
|
||||
return null;
|
||||
}
|
||||
case "filemoon":
|
||||
try {
|
||||
return await filemoonExtractor(html, url);
|
||||
|
|
@ -374,6 +384,13 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
console.log("Error extracting stream URL from filemoon:", error);
|
||||
return null;
|
||||
}
|
||||
case "lulustream":
|
||||
try {
|
||||
return await lulustreamExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from lulustream:", error);
|
||||
return null;
|
||||
}
|
||||
case "megacloud":
|
||||
try {
|
||||
return await megacloudExtractor(html, url);
|
||||
|
|
@ -388,6 +405,13 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
console.log("Error extracting stream URL from mp4upload:", error);
|
||||
return null;
|
||||
}
|
||||
case "sendvid":
|
||||
try {
|
||||
return await sendvidExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from sendvid:", error);
|
||||
return null;
|
||||
}
|
||||
case "sibnet":
|
||||
try {
|
||||
return await sibnetExtractor(html, url);
|
||||
|
|
@ -395,6 +419,34 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
console.log("Error extracting stream URL from sibnet:", error);
|
||||
return null;
|
||||
}
|
||||
case "streamtape":
|
||||
try {
|
||||
return await streamtapeExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from streamtape:", error);
|
||||
return null;
|
||||
}
|
||||
case "streamup":
|
||||
try {
|
||||
return await streamupExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from streamup:", error);
|
||||
return null;
|
||||
}
|
||||
case "supervideo":
|
||||
try {
|
||||
return await supervideoExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from supervideo:", error);
|
||||
return null;
|
||||
}
|
||||
case "uploadcx":
|
||||
try {
|
||||
return await uploadcxExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from uploadcx:", error);
|
||||
return null;
|
||||
}
|
||||
case "uqload":
|
||||
try {
|
||||
return await uqloadExtractor(html, url);
|
||||
|
|
@ -402,6 +454,13 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
console.log("Error extracting stream URL from uqload:", error);
|
||||
return null;
|
||||
}
|
||||
case "videospk":
|
||||
try {
|
||||
return await videospkExtractor(html, url);
|
||||
} catch (error) {
|
||||
console.log("Error extracting stream URL from videospk:", error);
|
||||
return null;
|
||||
}
|
||||
case "vidmoly":
|
||||
try {
|
||||
return await vidmolyExtractor(html, url);
|
||||
|
|
@ -430,17 +489,11 @@ async function extractStreamUrlByProvider(url, provider) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// EXTRACTORS //
|
||||
////////////////////////////////////////////////
|
||||
|
||||
// DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING //
|
||||
|
||||
|
||||
/* --- bigwarp --- */
|
||||
|
||||
/**
|
||||
|
|
@ -458,8 +511,6 @@ async function bigwarpExtractor(videoPage, url = null) {
|
|||
console.log("BigWarp HD Decoded:", bwDecoded);
|
||||
return bwDecoded;
|
||||
}
|
||||
|
||||
|
||||
/* --- doodstream --- */
|
||||
|
||||
/**
|
||||
|
|
@ -493,7 +544,27 @@ function randomStr(length) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
/* --- earnvids --- */
|
||||
|
||||
/* {REQUIRED PLUGINS: unbaser} */
|
||||
/**
|
||||
* @name earnvidsExtractor
|
||||
* @author 50/50
|
||||
*/
|
||||
async function earnvidsExtractor(html, url = null) {
|
||||
try {
|
||||
const obfuscatedScript = html.match(/<script[^>]*>\s*(eval\(function\(p,a,c,k,e,d.*?\)[\s\S]*?)<\/script>/);
|
||||
const unpackedScript = unpack(obfuscatedScript[1]);
|
||||
const streamMatch = unpackedScript.match(/["'](\/stream\/[^"']+)["']/);
|
||||
const hlsLink = streamMatch ? streamMatch[1] : null;
|
||||
const baseUrl = url.match(/^(https?:\/\/[^/]+)/)[1];
|
||||
console.log("HLS Link:" + baseUrl + hlsLink);
|
||||
return baseUrl + hlsLink;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return "https://files.catbox.moe/avolvc.mp4";
|
||||
}
|
||||
}
|
||||
|
||||
/* --- filemoon --- */
|
||||
|
||||
|
|
@ -549,8 +620,18 @@ async function filemoonExtractor(html, url = null) {
|
|||
}
|
||||
|
||||
|
||||
/* --- lulustream --- */
|
||||
|
||||
|
||||
/**
|
||||
* @name LuluStream Extractor
|
||||
* @author Cufiy
|
||||
*/
|
||||
async function lulustreamExtractor(data, url = null) {
|
||||
const scriptRegex = /sources:\s*\[\{file:"([^"]+)"/;
|
||||
const scriptMatch = scriptRegex.exec(data);
|
||||
const decoded = scriptMatch ? scriptMatch[1] : false;
|
||||
return decoded;
|
||||
}
|
||||
/* --- megacloud --- */
|
||||
|
||||
/**
|
||||
|
|
@ -560,16 +641,28 @@ async function filemoonExtractor(html, url = null) {
|
|||
|
||||
// Megacloud V3 specific
|
||||
async function megacloudExtractor(html, embedUrl) {
|
||||
// TESTING ONLY START
|
||||
const testcase = '/api/static';
|
||||
if(embedUrl.slice(-testcase.length) == testcase) {
|
||||
try {
|
||||
const response = await soraFetch(embedUrl, { method: 'GET', headers: { "referer": "https://megacloud.blog/" } });
|
||||
embedUrl = response.url;
|
||||
} catch (error) {
|
||||
throw new Error("[TESTING ONLY] Megacloud extraction error:", error);
|
||||
}
|
||||
}
|
||||
// TESTING ONLY END
|
||||
const CHARSET = Array.from({ length: 95 }, (_, i) => String.fromCharCode(i + 32));
|
||||
const xraxParams = embedUrl.split('/').pop();
|
||||
const xrax = xraxParams.includes('?') ? xraxParams.split('?')[0] : xraxParams;
|
||||
const nonce = await getNonce(embedUrl);
|
||||
// return decrypt(secretKey, nonce, encryptedText);
|
||||
try {
|
||||
const response = await fetch(`https://megacloud.blog/embed-2/v3/e-1/getSources?id=${xrax}&_k=${nonce}`);
|
||||
const response = await soraFetch(`https://megacloud.blog/embed-2/v3/e-1/getSources?id=${xrax}&_k=${nonce}`, { method: 'GET', headers: { "referer": "https://megacloud.blog/" } });
|
||||
const rawSourceData = await response.json();
|
||||
const encrypted = rawSourceData?.sources;
|
||||
let decryptedSources = null;
|
||||
// console.log('rawSourceData', rawSourceData);
|
||||
if (rawSourceData?.encrypted == false) {
|
||||
decryptedSources = rawSourceData.sources;
|
||||
}
|
||||
|
|
@ -577,14 +670,14 @@ async function megacloudExtractor(html, embedUrl) {
|
|||
decryptedSources = await getDecryptedSourceV3(encrypted, nonce);
|
||||
if (!decryptedSources) throw new Error("Failed to decrypt source");
|
||||
}
|
||||
console.log("Decrypted sources:" + JSON.stringify(decryptedSources, null, 2));
|
||||
// console.log("Decrypted sources:" + JSON.stringify(decryptedSources, null, 2));
|
||||
// return the first source if it's an array
|
||||
if (Array.isArray(decryptedSources) && decryptedSources.length > 0) {
|
||||
try {
|
||||
return decryptedSources[0].file;
|
||||
} catch (error) {
|
||||
console.log("Error extracting MegaCloud stream URL:" + error);
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// return {
|
||||
|
|
@ -774,7 +867,7 @@ async function megacloudExtractor(html, embedUrl) {
|
|||
* @returns {string|null} The extracted nonce, or null if it couldn't be found
|
||||
*/
|
||||
async function getNonce(embedUrl) {
|
||||
const res = await fetch(embedUrl, { headers: { "referer": "https://anicrush.to/", "x-requested-with": "XMLHttpRequest" } });
|
||||
const res = await soraFetch(embedUrl, { headers: { "referer": "https://anicrush.to/", "x-requested-with": "XMLHttpRequest" } });
|
||||
const html = await res.text();
|
||||
const match0 = html.match(/\<meta[\s\S]*?name="_gg_fb"[\s\S]*?content="([\s\S]*?)">/);
|
||||
if (match0?.[1]) {
|
||||
|
|
@ -857,10 +950,10 @@ async function megacloudExtractor(html, embedUrl) {
|
|||
}
|
||||
return keys;
|
||||
}
|
||||
function fetchKey(name, url, timeout = 1000) {
|
||||
function fetchKey(name, url) {
|
||||
return new Promise(async (resolve) => {
|
||||
try {
|
||||
const response = await fetch(url, { method: 'get', timeout: timeout });
|
||||
const response = await soraFetch(url, { method: 'get' });
|
||||
const key = await response.text();
|
||||
let trueKey = null;
|
||||
try {
|
||||
|
|
@ -875,8 +968,6 @@ async function megacloudExtractor(html, embedUrl) {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* --- mp4upload --- */
|
||||
|
||||
/**
|
||||
|
|
@ -894,8 +985,17 @@ async function mp4uploadExtractor(html, url = null) {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
/* --- sendvid --- */
|
||||
|
||||
|
||||
/**
|
||||
* @name sendvidExtractor
|
||||
* @author 50/50
|
||||
*/
|
||||
async function sendvidExtractor(data, url = null) {
|
||||
const match = data.match(/var\s+video_source\s*=\s*"([^"]+)"/);
|
||||
const videoUrl = match ? match[1] : null;
|
||||
return videoUrl;
|
||||
}
|
||||
/* --- sibnet --- */
|
||||
|
||||
/**
|
||||
|
|
@ -920,8 +1020,119 @@ async function sibnetExtractor(html, embedUrl) {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
/* --- streamtape --- */
|
||||
|
||||
/**
|
||||
*
|
||||
* @name streamTapeExtractor
|
||||
* @author ShadeOfChaos
|
||||
*/
|
||||
async function streamtapeExtractor(html, url) {
|
||||
let promises = [];
|
||||
const LINK_REGEX = /link['"]{1}\).innerHTML *= *['"]{1}([\s\S]*?)["'][\s\S]*?\(["']([\s\S]*?)["']([\s\S]*?);/g;
|
||||
const CHANGES_REGEX = /([0-9]+)/g;
|
||||
if(html == null) {
|
||||
if(url == null) {
|
||||
throw new Error('Provided incorrect parameters.');
|
||||
}
|
||||
const response = await soraFetch(url);
|
||||
html = await response.text();
|
||||
}
|
||||
const matches = html.matchAll(LINK_REGEX);
|
||||
for (const match of matches) {
|
||||
let base = match?.[1];
|
||||
let params = match?.[2];
|
||||
const changeStr = match?.[3];
|
||||
if(changeStr == null || changeStr == '') continue;
|
||||
const changes = changeStr.match(CHANGES_REGEX);
|
||||
for(let n of changes) {
|
||||
params = params.substring(n);
|
||||
}
|
||||
while(base[0] == '/') {
|
||||
base = base.substring(1);
|
||||
}
|
||||
const url = 'https://' + base + params;
|
||||
promises.push(testUrl(url));
|
||||
}
|
||||
// Race for first success
|
||||
return Promise.any(promises).then((value) => {
|
||||
return value;
|
||||
}).catch((error) => {
|
||||
return null;
|
||||
});
|
||||
async function testUrl(url) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
// Timeout version prefered, but Sora does not support it currently
|
||||
// var response = await soraFetch(url, { method: 'GET', signal: AbortSignal.timeout(2000) });
|
||||
var response = await soraFetch(url);
|
||||
if(response == null) throw new Error('Connection timed out.');
|
||||
} catch(e) {
|
||||
console.error('Rejected due to:', e.message);
|
||||
return reject(null);
|
||||
}
|
||||
if(response?.ok && response?.status === 200) {
|
||||
return resolve(url);
|
||||
}
|
||||
console.warn('Reject because of response:', response?.ok, response?.status);
|
||||
return reject(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
/* --- streamup --- */
|
||||
|
||||
/**
|
||||
* @name StreamUp Extractor
|
||||
* @author Cufiy
|
||||
*/
|
||||
async function streamupExtractor(data, url = null) {
|
||||
// if url ends with /, remove it
|
||||
if (url.endsWith("/")) {
|
||||
url = url.slice(0, -1);
|
||||
}
|
||||
// split the url by / and get the last part
|
||||
const urlParts = url.split("/");
|
||||
const videoId = urlParts[urlParts.length - 1];
|
||||
const apiUrl = `https://strmup.to/ajax/stream?filecode=${videoId}`;
|
||||
const response = await soraFetch(apiUrl);
|
||||
const jsonData = await response.json();
|
||||
if (jsonData && jsonData.streaming_url) {
|
||||
return jsonData.streaming_url;
|
||||
} else {
|
||||
console.log("No streaming URL found in the response.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/* --- supervideo --- */
|
||||
|
||||
/* {REQUIRED PLUGINS: unbaser} */
|
||||
/**
|
||||
* @name SuperVideo Extractor
|
||||
* @author 50/50
|
||||
*/
|
||||
async function supervideoExtractor(data, url = null) {
|
||||
const obfuscatedScript = data.match(/<script[^>]*>\s*(eval\(function\(p,a,c,k,e,d.*?\)[\s\S]*?)<\/script>/);
|
||||
const unpackedScript = unpack(obfuscatedScript[1]);
|
||||
const regex = /file:\s*"([^"]+\.m3u8)"/;
|
||||
const match = regex.exec(unpackedScript);
|
||||
if (match) {
|
||||
const fileUrl = match[1];
|
||||
console.log("File URL:" + fileUrl);
|
||||
return fileUrl;
|
||||
}
|
||||
return "No stream found";
|
||||
}
|
||||
|
||||
/* --- uploadcx --- */
|
||||
|
||||
/**
|
||||
* @name UploadCx Extractor
|
||||
* @author 50/50
|
||||
*/
|
||||
async function uploadcxExtractor(data, url = null) {
|
||||
const mp4Match = /sources:\s*\["([^"]+\.mp4)"]/i.exec(data);
|
||||
return mp4Match ? mp4Match[1] : null;
|
||||
}
|
||||
/* --- uqload --- */
|
||||
|
||||
/**
|
||||
|
|
@ -938,7 +1149,20 @@ async function uqloadExtractor(html, embedUrl) {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
/* --- videospk --- */
|
||||
|
||||
/* {REQUIRED PLUGINS: unbaser} */
|
||||
/**
|
||||
* @name videospkExtractor
|
||||
* @author 50/50
|
||||
*/
|
||||
async function videospkExtractor(data, url = null) {
|
||||
const obfuscatedScript = data.match(/<script[^>]*>\s*(eval\(function\(p,a,c,k,e,d.*?\)[\s\S]*?)<\/script>/);
|
||||
const unpackedScript = unpack(obfuscatedScript[1]);
|
||||
const streamMatch = unpackedScript.match(/["'](\/stream\/[^"']+)["']/);
|
||||
const hlsLink = streamMatch ? streamMatch[1] : null;
|
||||
return "https://videospk.xyz" + hlsLink;
|
||||
}
|
||||
|
||||
/* --- vidmoly --- */
|
||||
|
||||
|
|
@ -978,8 +1202,6 @@ async function vidmolyExtractor(html, url = null) {
|
|||
return sourcesString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* --- vidoza --- */
|
||||
|
||||
/**
|
||||
|
|
@ -996,8 +1218,6 @@ async function vidozaExtractor(html, url = null) {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* --- voe --- */
|
||||
|
||||
/**
|
||||
|
|
@ -1093,10 +1313,6 @@ function voeShiftChars(str, shift) {
|
|||
.join("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// PLUGINS //
|
||||
////////////////////////////////////////////////
|
||||
|
|
@ -1126,7 +1342,11 @@ async function soraFetch(url, options = { headers: {}, method: 'GET', body: null
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* UNPACKER MODULE
|
||||
* Credit to GitHub user "mnsrulz" for Unpacker Node library
|
||||
* https://github.com/mnsrulz/unpacker
|
||||
***********************************************************/
|
||||
class Unbaser {
|
||||
constructor(base) {
|
||||
this.ALPHABET = {
|
||||
|
|
@ -1163,6 +1383,10 @@ class Unbaser {
|
|||
}
|
||||
}
|
||||
|
||||
function detectUnbaser(source) {
|
||||
/* Detects whether `source` is P.A.C.K.E.R. coded. */
|
||||
return source.replace(" ", "").startsWith("eval(function(p,a,c,k,e,");
|
||||
}
|
||||
|
||||
function unpack(source) {
|
||||
let { payload, symtab, radix, count } = _filterargs(source);
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
"sourceName": "DoraBash",
|
||||
"iconUrl": "https://dorabash.com/wp-content/uploads/2023/06/cropped-Untitled_design-removebg-192x192.png",
|
||||
"author": {
|
||||
"name": "50/50",
|
||||
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
|
||||
},
|
||||
"version": "1.0.1",
|
||||
"language": "Hindi",
|
||||
"streamType": "HLS",
|
||||
"quality": "1080p",
|
||||
"baseUrl": "https://dorabash.com/",
|
||||
"searchBaseUrl": "https://dorabash.com/",
|
||||
"scriptUrl": "https://git.luna-app.eu/50n50/sources/raw/branch/main/dorabash/dorabash.js",
|
||||
"type": "anime",
|
||||
"asyncJS": true,
|
||||
"softsub": false,
|
||||
"downloadSupport": false
|
||||
}
|
||||
"sourceName": "DoraBash",
|
||||
"iconUrl": "https://dorabash.com/wp-content/uploads/2023/06/cropped-Untitled_design-removebg-192x192.png",
|
||||
"author": {
|
||||
"name": "50/50",
|
||||
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
|
||||
},
|
||||
"version": "1.0.2",
|
||||
"language": "Hindi",
|
||||
"streamType": "HLS",
|
||||
"quality": "1080p",
|
||||
"baseUrl": "https://dorabash.com/",
|
||||
"searchBaseUrl": "https://dorabash.com/",
|
||||
"scriptUrl": "https://git.luna-app.eu/50n50/sources/raw/branch/main/dorabash/dorabash.js",
|
||||
"type": "anime",
|
||||
"asyncJS": true,
|
||||
"softsub": false,
|
||||
"downloadSupport": false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue