mirror of
https://git.luna-app.eu/50n50/sources
synced 2026-01-11 00:48:12 +01:00
Update checkmate/checkmate.js
This commit is contained in:
parent
9fec9d8fff
commit
5fdb173990
1 changed files with 63 additions and 399 deletions
|
|
@ -317,59 +317,58 @@ async function extractEpisodes(url) {
|
|||
|
||||
async function extractStreamUrl(ID) {
|
||||
try {
|
||||
let subtitle = null;
|
||||
if (ID.includes('movie')) {
|
||||
const tmdbID = ID.split('/')[2];
|
||||
const subResponse = await fetchv2(`https://sub.wyzie.ru/search?id=${tmdbID}&format=srt`);
|
||||
const subtitles = await subResponse.json();
|
||||
subtitle = subtitles.find(sub => sub.language.toLowerCase() === 'en')?.url || null;
|
||||
} else if (ID.includes('tv')) {
|
||||
const parts = ID.split('/');
|
||||
const tmdbID = parts[2];
|
||||
const seasonNumber = parts[3];
|
||||
const episodeNumber = parts[4];
|
||||
const subResponse = await fetchv2(`https://sub.wyzie.ru/search?id=${tmdbID}&format=srt&season=${seasonNumber}&episode=${episodeNumber}`);
|
||||
const subtitles = await subResponse.json();
|
||||
subtitle = subtitles.find(sub => sub.language.toLowerCase() === 'en')?.url || null;
|
||||
}
|
||||
const alphaPromise = alpha(ID).then(result => ({ source: 'alpha', data: JSON.parse(result) })).catch(err => ({ source: 'alpha', error: err }));
|
||||
const betaPromise = beta(ID).then(result => ({ source: 'beta', data: JSON.parse(result) })).catch(err => ({ source: 'beta', error: err }));
|
||||
const gammaPromise = gamma(ID).then(result => ({ source: 'gamma', data: JSON.parse(result) })).catch(err => ({ source: 'gamma', error: err }));
|
||||
const deltaPromise = delta(ID).then(result => ({ source: 'delta', data: JSON.parse(result) })).catch(err => ({ source: 'delta', error: err }));
|
||||
const epsilonPromise = epsilon(ID).then(result => ({ source: 'epsilon', data: JSON.parse(result) })).catch(err => ({ source: 'epsilon', error: err }));
|
||||
|
||||
const racePromise = Promise.race([alphaPromise, gammaPromise, deltaPromise]);
|
||||
|
||||
const [fastestResult, betaResult, alphaResult] = await Promise.all([racePromise, betaPromise, alphaPromise]);
|
||||
const [fastestResult, alphaResult] = await Promise.all([racePromise, alphaPromise]);
|
||||
|
||||
let epsilonResult = null;
|
||||
const alphaHas4K = alphaResult && !alphaResult.error && alphaResult.data && alphaResult.data.streams &&
|
||||
alphaResult.data.streams.some((_, i, arr) => i % 2 === 0 && arr[i] && arr[i].toLowerCase().includes('4k'));
|
||||
|
||||
if (!alphaHas4K) {
|
||||
epsilonResult = await epsilonPromise;
|
||||
}
|
||||
|
||||
const resultStreams = [];
|
||||
let subtitle = null;
|
||||
|
||||
if (fastestResult && !fastestResult.error && fastestResult.data && fastestResult.data.streams && fastestResult.data.streams.length > 0) {
|
||||
const streamUrl = fastestResult.data.streams.length >= 2 ? fastestResult.data.streams[1] : fastestResult.data.streams[0];
|
||||
let streamUrl;
|
||||
let headers = {};
|
||||
if (typeof fastestResult.data.streams[0] === 'string') {
|
||||
streamUrl = fastestResult.data.streams.length >= 2 ? fastestResult.data.streams[1] : fastestResult.data.streams[0];
|
||||
} else {
|
||||
streamUrl = fastestResult.data.streams[0].streamUrl;
|
||||
headers = fastestResult.data.streams[0].headers || {};
|
||||
}
|
||||
|
||||
resultStreams.push({
|
||||
title: "Default (1080p)",
|
||||
streamUrl: streamUrl,
|
||||
headers: fastestResult.data.referer ? { "Referer": fastestResult.data.referer } : {}
|
||||
headers: { ...headers, ...(fastestResult.data.referer ? { "Referer": fastestResult.data.referer } : {}) }
|
||||
});
|
||||
|
||||
subtitle = fastestResult.data.subtitles || null;
|
||||
|
||||
} else {
|
||||
if (betaResult && !betaResult.error && betaResult.data && betaResult.data.streams && betaResult.data.streams.length > 0) {
|
||||
const streamUrl = betaResult.data.streams.length >= 2 ? betaResult.data.streams[1] : betaResult.data.streams[0];
|
||||
|
||||
resultStreams.push({
|
||||
title: "Default (1080p)",
|
||||
streamUrl: streamUrl,
|
||||
headers: betaResult.data.referer ? { "Referer": betaResult.data.referer } : {}
|
||||
});
|
||||
|
||||
subtitle = betaResult.data.subtitles || null;
|
||||
}
|
||||
}
|
||||
|
||||
if (alphaResult && !alphaResult.error && alphaResult.data && alphaResult.data.streams) {
|
||||
const streams = alphaResult.data.streams;
|
||||
let fourKUrl = null;
|
||||
let fourKHeaders = {};
|
||||
|
||||
for (let i = 0; i < streams.length; i += 2) {
|
||||
if (streams[i] && streams[i].toLowerCase().includes('4k') && streams[i + 1]) {
|
||||
fourKUrl = streams[i + 1];
|
||||
for (let stream of streams) {
|
||||
if (stream.title && stream.title.toLowerCase().includes('4k') && stream.streamUrl) {
|
||||
fourKUrl = stream.streamUrl;
|
||||
fourKHeaders = stream.headers || {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -378,36 +377,10 @@ async function extractStreamUrl(ID) {
|
|||
resultStreams.push({
|
||||
title: "4K",
|
||||
streamUrl: fourKUrl,
|
||||
headers: {
|
||||
"Origin": "https://player.videasy.net",
|
||||
"Referer": "https://player.videasy.net/"
|
||||
}
|
||||
headers: fourKHeaders
|
||||
});
|
||||
} else {
|
||||
console.log('Alpha did not return a 4K stream, checking epsilon as fallback');
|
||||
|
||||
if (epsilonResult && !epsilonResult.error && epsilonResult.data && epsilonResult.data.streams) {
|
||||
const epsilonStreams = epsilonResult.data.streams;
|
||||
let epsilonFourKUrl = null;
|
||||
|
||||
for (const stream of epsilonStreams) {
|
||||
if (stream.title && stream.title.includes('4K') && stream.streamUrl) {
|
||||
epsilonFourKUrl = stream;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (epsilonFourKUrl) {
|
||||
console.log('Using epsilon as 4K fallback provider');
|
||||
resultStreams.push({
|
||||
title: "4K",
|
||||
streamUrl: epsilonFourKUrl.streamUrl,
|
||||
headers: epsilonFourKUrl.headers || { "Referer": "https://mapple.uk/", "Origin": "https://mapple.uk" }
|
||||
});
|
||||
} else {
|
||||
console.log('Epsilon fallback also did not return a 4K stream');
|
||||
}
|
||||
}
|
||||
console.log('Alpha did not return a 4K stream');
|
||||
}
|
||||
}
|
||||
console.log(JSON.stringify({
|
||||
|
|
@ -457,7 +430,7 @@ async function alpha(ID) {
|
|||
const imdbId = cinebyData.external_ids?.imdb_id || '';
|
||||
const tmdbId = cinebyData.id;
|
||||
|
||||
const fullUrl = `https://api.videasy.net/myflixerzupcloud/sources-with-title?title=${title}&mediaType=movie&year=${year}&episodeId=1&seasonId=1&tmdbId=${tmdbId}&imdbId=${imdbId}`;
|
||||
const fullUrl = `https://api.videasy.net/cdn/sources-with-title?title=${title}&mediaType=movie&year=${year}&episodeId=1&seasonId=1&tmdbId=${tmdbId}&imdbId=${imdbId}`;
|
||||
|
||||
console.log('Full URL:' + fullUrl);
|
||||
|
||||
|
|
@ -472,9 +445,9 @@ async function alpha(ID) {
|
|||
|
||||
const postData = JSON.stringify({
|
||||
text: encrypted,
|
||||
id: tmdbID
|
||||
id: tmdbID.split('-')[0]
|
||||
});
|
||||
|
||||
console.log('Post Data:' + postData);
|
||||
const decryptedResponse = await fetchv2("https://enc-dec.app/api/dec-videasy", headers, "POST", postData);
|
||||
const decryptedData = await decryptedResponse.json();
|
||||
console.log('Decrypted Data:' + JSON.stringify(decryptedData));
|
||||
|
|
@ -485,15 +458,22 @@ async function alpha(ID) {
|
|||
|
||||
const nonHDRSources = sources.filter(s => !s.quality.includes("HDR"));
|
||||
|
||||
const streams = nonHDRSources.flatMap(src => [src.quality, src.url]);
|
||||
const streamObjects = nonHDRSources.map(src => ({
|
||||
title: src.quality,
|
||||
streamUrl: src.url,
|
||||
headers: {
|
||||
"Origin": "https://player.videasy.net",
|
||||
"Referer": "https://player.videasy.net/"
|
||||
}
|
||||
}));
|
||||
|
||||
const englishSubtitle = subtitles.find(
|
||||
sub => sub.language.toLowerCase().includes('english')
|
||||
)?.url || null;
|
||||
|
||||
return JSON.stringify({
|
||||
streams,
|
||||
subtitles: englishSubtitle
|
||||
streams: streamObjects,
|
||||
subtitle: englishSubtitle
|
||||
});
|
||||
} else if (ID.includes('tv')) {
|
||||
const parts = ID.split('/');
|
||||
|
|
@ -501,7 +481,7 @@ async function alpha(ID) {
|
|||
const seasonNumber = parts[3];
|
||||
const episodeNumber = parts[4];
|
||||
|
||||
const cinebyResponse = await soraFetch(`hhttps://db.videasy.net/3/tv/${tmdbID}?append_to_response=external_ids&language=en&api_key=ad301b7cc82ffe19273e55e4d4206885`);
|
||||
const cinebyResponse = await soraFetch(`https://db.videasy.net/3/tv/${tmdbID}?append_to_response=external_ids&language=en&api_key=ad301b7cc82ffe19273e55e4d4206885`);
|
||||
const cinebyData = await cinebyResponse.json();
|
||||
|
||||
const title = encodeURIComponent(cinebyData.name);
|
||||
|
|
@ -509,7 +489,7 @@ async function alpha(ID) {
|
|||
const imdbId = cinebyData.external_ids?.imdb_id || '';
|
||||
const tmdbId = cinebyData.id;
|
||||
|
||||
const fullUrl = `https://api.videasy.net/myflixerzupcloud/sources-with-title?title==${title}&mediaType=tv&year=${year}&episodeId=${episodeNumber}&seasonId=${seasonNumber}&tmdbId=${tmdbId}&imdbId=${imdbId}`;
|
||||
const fullUrl = `https://api.videasy.net/cdn/sources-with-title?title=${title}&mediaType=tv&year=${year}&episodeId=${episodeNumber}&seasonId=${seasonNumber}&tmdbId=${tmdbId}&imdbId=${imdbId}`;
|
||||
|
||||
console.log('Full URL:' + fullUrl);
|
||||
|
||||
|
|
@ -524,7 +504,7 @@ async function alpha(ID) {
|
|||
|
||||
const postData = JSON.stringify({
|
||||
text: encrypted,
|
||||
id: tmdbID
|
||||
id: tmdbID.split('-')[0]
|
||||
});
|
||||
|
||||
const decryptedResponse = await fetchv2("https://enc-dec.app/api/dec-videasy", headers, "POST", postData);
|
||||
|
|
@ -537,101 +517,26 @@ async function alpha(ID) {
|
|||
|
||||
const nonHDRSources = sources.filter(s => !s.quality.includes("HDR"));
|
||||
|
||||
const streams = nonHDRSources.flatMap(src => [src.quality, src.url]);
|
||||
const streamObjects = nonHDRSources.map(src => ({
|
||||
title: src.quality,
|
||||
streamUrl: src.url,
|
||||
headers: {
|
||||
"Origin": "https://player.videasy.net",
|
||||
"Referer": "https://player.videasy.net/"
|
||||
}
|
||||
}));
|
||||
|
||||
const englishSubtitle = subtitles.find(
|
||||
sub => sub.language.toLowerCase().includes('english')
|
||||
)?.url || null;
|
||||
|
||||
return JSON.stringify({
|
||||
streams,
|
||||
subtitles: englishSubtitle
|
||||
streams: streamObjects,
|
||||
subtitle: englishSubtitle
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function beta(ID) {
|
||||
if (ID.includes('movie')) {
|
||||
const tmdbID = ID.replace('/movie/', '');
|
||||
const headersOne = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI2NTQ0MWU0MTg4NjhhMWI0NDZiM2I0Mzg1MmE4OWQ2NyIsIm5iZiI6MTYzMDg4NDI0My40NzMsInN1YiI6IjYxMzU1MTkzZmQ0YTk2MDA0NDVkMTJjNiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.Hm0W-hUx-7ph-ASvk2TpMxZbMtwVa5DEXWcgNgcqXJM",
|
||||
"Referer": "https://player.smashystream.com/",
|
||||
"Origin": "https://player.smashystream.com",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"
|
||||
};
|
||||
const tmdbResponse = await fetchv2(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/movie/${tmdbID}?append_to_response=external_ids`)}&simple=true`, headersOne);
|
||||
const tmdbData = await tmdbResponse.json();
|
||||
const imdbID = tmdbData.imdb_id;
|
||||
|
||||
const streamResponse = await ilovefeet(imdbID, false, null, null, 'm3u8');
|
||||
|
||||
const streams = [];
|
||||
|
||||
if (streamResponse && streamResponse.defaultUrl) {
|
||||
streams.push("1080p", streamResponse.defaultUrl);
|
||||
}
|
||||
|
||||
if (streamResponse && streamResponse.vFastUrl) {
|
||||
const fourKResult = await ilovearmpits(streamResponse.vFastUrl);
|
||||
if (fourKResult.available && fourKResult.url) {
|
||||
streams.push("4K", fourKResult.url);
|
||||
}
|
||||
}
|
||||
|
||||
const final = {
|
||||
streams,
|
||||
subtitles: streamResponse.subtitles || "None",
|
||||
referer: "https://vidfast.pro/"
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(final));
|
||||
return JSON.stringify(final);
|
||||
} else if (ID.includes('tv')) {
|
||||
const parts = ID.split('/');
|
||||
const tmdbID = parts[2];
|
||||
const seasonNumber = parts[3];
|
||||
const episodeNumber = parts[4];
|
||||
console.log(`TMDB ID: ${tmdbID}, Season: ${seasonNumber}, Episode: ${episodeNumber}`);
|
||||
const headersOne = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI2NTQ0MWU0MTg4NjhhMWI0NDZiM2I0Mzg1MmE4OWQ2NyIsIm5iZiI6MTYzMDg4NDI0My40NzMsInN1YiI6IjYxMzU1MTkzZmQ0YTk2MDA0NDVkMTJjNiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.Hm0W-hUx-7ph-ASvk2TpMxZbMtwVa5DEXWcgNgcqXJM",
|
||||
"Referer": "https://player.smashystream.com/",
|
||||
"Origin": "https://player.smashystream.com",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"
|
||||
};
|
||||
const tmdbResponse = await fetchv2(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/${tmdbID}?append_to_response=external_ids`)}&simple=true`, headersOne);
|
||||
const tmdbData = await tmdbResponse.json();
|
||||
const imdbID = tmdbData.external_ids.imdb_id;
|
||||
|
||||
const streamResponse = await ilovefeet(imdbID, true, seasonNumber, episodeNumber, 'm3u8');
|
||||
|
||||
const streams = [];
|
||||
|
||||
if (streamResponse && streamResponse.defaultUrl) {
|
||||
streams.push("1080p", streamResponse.defaultUrl);
|
||||
}
|
||||
|
||||
if (streamResponse && streamResponse.vFastUrl) {
|
||||
const fourKResult = await ilovearmpits(streamResponse.vFastUrl);
|
||||
if (fourKResult.available && fourKResult.url) {
|
||||
streams.push("4K", fourKResult.url);
|
||||
}
|
||||
}
|
||||
|
||||
const final = {
|
||||
streams,
|
||||
subtitles: streamResponse.subtitles || "None",
|
||||
referer: "https://vidfast.pro/"
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(final));
|
||||
return JSON.stringify(final);
|
||||
}
|
||||
}
|
||||
|
||||
async function gamma(ID) {
|
||||
if (ID.includes('movie')) {
|
||||
const parts = ID.split('/');
|
||||
|
|
@ -690,9 +595,9 @@ async function delta(ID) {
|
|||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
|
||||
"X-Api-Key": "24ef089ebcab51d107a4e4709e87861ef609bace89ac23af13235f6ea743488f"
|
||||
};
|
||||
const response = await fetchv2(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://themoviedb.hexa.watch/api/tmdb/movie/${ID.split('/')[2]}/images`)}&simple=true`, headersOne);
|
||||
const response = await fetchv2(`https://themoviedb.hexa.su/api/tmdb/movie/${ID.split('/')[2]}/images`, headersOne);
|
||||
const data = await response.text();
|
||||
|
||||
console.log('Encrypted Data:' + data);
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
|
|
@ -725,8 +630,7 @@ async function delta(ID) {
|
|||
|
||||
return JSON.stringify({
|
||||
streams,
|
||||
subtitles: englishSubtitle,
|
||||
referer: "https://hexa.watch/"
|
||||
subtitles: englishSubtitle
|
||||
});
|
||||
} else if (ID.includes('tv')) {
|
||||
const parts = ID.split('/');
|
||||
|
|
@ -737,7 +641,7 @@ async function delta(ID) {
|
|||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
|
||||
"X-Api-Key": "24ef089ebcab51d107a4e4709e87861ef609bace89ac23af13235f6ea743488f"
|
||||
};
|
||||
const response = await fetchv2(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://themoviedb.hexa.watch/api/tmdb/tv/${tmdbID}/season/${seasonNumber}/episode/${episodeNumber}/images`)}&simple=true`, headersOne);
|
||||
const response = await fetchv2(`https://themoviedb.hexa.su/api/tmdb/tv/${tmdbID}/season/${seasonNumber}/episode/${episodeNumber}/images`, headersOne);
|
||||
const data = await response.text();
|
||||
|
||||
const headers = {
|
||||
|
|
@ -772,208 +676,11 @@ async function delta(ID) {
|
|||
|
||||
return JSON.stringify({
|
||||
streams,
|
||||
subtitles: null,
|
||||
referer: "https://hexa.watch/"
|
||||
subtitles: englishSubtitle
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function epsilon(ID) {
|
||||
const actionIdentifier = await ilovethighs("https://mapple.uk/watch/movie/1061474-superman");
|
||||
|
||||
console.log("Action Identifier: " + actionIdentifier);
|
||||
|
||||
const sessionResponse = await soraFetch("https://enc-dec.app/api/enc-mapple");
|
||||
const sessionData = await sessionResponse.json();
|
||||
console.log("Session Data: " + JSON.stringify(sessionData));
|
||||
const sessionID = sessionData.result.sessionId || "N/A";
|
||||
console.log("ID: " + ID);
|
||||
if (ID.startsWith('/movie/') || ID.startsWith('movie/')) {
|
||||
const match = ID.match(/movie\/(\d+)/);
|
||||
const tmdbID = match ? match[1] : '';
|
||||
console.log("Extracted TMDB ID: " + tmdbID);
|
||||
const headers = {
|
||||
"Content-Type": "text/plain",
|
||||
"next-action": actionIdentifier
|
||||
};
|
||||
const postData = `[{"mediaId":${tmdbID},"mediaType":"movie","tv_slug":"","source":"mapple","useFallbackVideo":false,"sessionId":"${sessionID}"}]`;
|
||||
const response = await fetchv2("https://mapple.uk/watch/"+ ID, headers, "POST", postData);
|
||||
const data = await response.text();
|
||||
console.log("Stream data: " + data);
|
||||
|
||||
const lines = data.split('\n');
|
||||
let streamData = null;
|
||||
for (const line of lines) {
|
||||
if (line.includes('"success":true')) {
|
||||
streamData = JSON.parse(line.substring(line.indexOf('{')));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (streamData && streamData.data && streamData.data.stream_url) {
|
||||
const m3u8Response = await soraFetch(streamData.data.stream_url, {
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
const m3u8Text = await m3u8Response.text();
|
||||
console.log("M3U8 Playlist: " + m3u8Text);
|
||||
|
||||
const streams = [];
|
||||
const lines = m3u8Text.split('\n');
|
||||
const resolutionNames = {
|
||||
"3840x2160": "4K",
|
||||
"1920x1080": "1080p",
|
||||
"1280x720": "720p",
|
||||
"640x360": "360p"
|
||||
};
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].startsWith('#EXT-X-STREAM-INF')) {
|
||||
const resolutionMatch = lines[i].match(/RESOLUTION=(\d+x\d+)/);
|
||||
const streamUrl = lines[i + 1];
|
||||
if (resolutionMatch && streamUrl && streamUrl.trim()) {
|
||||
const resolution = resolutionMatch[1];
|
||||
const friendlyName = resolutionNames[resolution] || resolution;
|
||||
streams.push({
|
||||
title: friendlyName,
|
||||
streamUrl: streamUrl.trim(),
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let englishSubtitleUrl = "";
|
||||
try {
|
||||
const subResponse = await soraFetch(`https://mapple.uk/api/subtitles?id=${tmdbID}&mediaType=movie`);
|
||||
const subData = await subResponse.json();
|
||||
const englishSub = subData.find(sub => sub.language === "en");
|
||||
if (englishSub) {
|
||||
englishSubtitleUrl = englishSub.url;
|
||||
}
|
||||
} catch (e) {
|
||||
englishSubtitleUrl = "";
|
||||
}
|
||||
console.log("English Subtitle URL: " + englishSubtitleUrl);
|
||||
console.log("Extracted streams: " + JSON.stringify(streams));
|
||||
|
||||
return JSON.stringify({
|
||||
streams: streams.length > 0 ? streams : [
|
||||
{
|
||||
title: "Mapple Server",
|
||||
streamUrl: streamData.data.stream_url,
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
}
|
||||
],
|
||||
subtitle: englishSubtitleUrl || ""
|
||||
});
|
||||
} else {
|
||||
throw new Error("Failed to extract stream URL");
|
||||
}
|
||||
} else if (ID.startsWith('/tv/') || ID.startsWith('tv/')) {
|
||||
const match = ID.match(/tv\/(\d+)-(\d+)-(\d+)/);
|
||||
if (!match) throw new Error("Invalid TV URL format");
|
||||
|
||||
const tmdbID = match[1];
|
||||
const seasonNumber = match[2];
|
||||
const episodeNumber = match[3];
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "text/plain",
|
||||
"next-action": actionIdentifier
|
||||
};
|
||||
const postData = `[{"mediaId":${tmdbID},"mediaType":"tv","tv_slug":"${seasonNumber}-${episodeNumber}","source":"mapple","useFallbackVideo":false,"sessionId":"${sessionID}"}]`;
|
||||
const response = await fetchv2("https://mapple.uk/watch"+ ID, headers, "POST", postData);
|
||||
const data = await response.text();
|
||||
console.log("Stream data: " + data);
|
||||
|
||||
const lines = data.split('\n');
|
||||
let streamData = null;
|
||||
for (const line of lines) {
|
||||
if (line.includes('"success":true')) {
|
||||
streamData = JSON.parse(line.substring(line.indexOf('{')));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (streamData && streamData.data && streamData.data.stream_url) {
|
||||
const m3u8Response = await soraFetch(streamData.data.stream_url, {
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
const m3u8Text = await m3u8Response.text();
|
||||
console.log("M3U8 Playlist: " + m3u8Text);
|
||||
|
||||
const streams = [];
|
||||
const lines = m3u8Text.split('\n');
|
||||
const resolutionNames = {
|
||||
"3840x2160": "4K",
|
||||
"1920x1080": "1080p",
|
||||
"1280x720": "720p",
|
||||
"640x360": "360p"
|
||||
};
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].startsWith('#EXT-X-STREAM-INF')) {
|
||||
const resolutionMatch = lines[i].match(/RESOLUTION=(\d+x\d+)/);
|
||||
const streamUrl = lines[i + 1];
|
||||
if (resolutionMatch && streamUrl && streamUrl.trim()) {
|
||||
const resolution = resolutionMatch[1];
|
||||
const friendlyName = resolutionNames[resolution] || resolution;
|
||||
streams.push({
|
||||
title: friendlyName,
|
||||
streamUrl: streamUrl.trim(),
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let englishSubtitleUrl = "";
|
||||
try {
|
||||
const subResponse = await soraFetch(`https://mapple.uk/api/subtitles?id=${tmdbID}&mediaType=tv&season=${seasonNumber}&episode=${episodeNumber}`);
|
||||
const subData = await subResponse.json();
|
||||
const englishSub = subData.find(sub => sub.language === "en");
|
||||
if (englishSub) {
|
||||
englishSubtitleUrl = englishSub.url;
|
||||
}
|
||||
} catch (e) {
|
||||
englishSubtitleUrl = "";
|
||||
}
|
||||
console.log("English Subtitle URL: " + englishSubtitleUrl);
|
||||
console.log("Extracted streams: " + JSON.stringify(streams));
|
||||
|
||||
return JSON.stringify({
|
||||
streams: streams.length > 0 ? streams : [
|
||||
{
|
||||
title: "Mapple Server",
|
||||
streamUrl: streamData.data.stream_url,
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
}
|
||||
],
|
||||
subtitle: englishSubtitleUrl || ""
|
||||
});
|
||||
} else {
|
||||
throw new Error("Failed to extract stream URL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function soraFetch(url, options = { headers: {}, method: 'GET', body: null, encoding: 'utf-8' }) {
|
||||
try {
|
||||
return await fetchv2(
|
||||
|
|
@ -1362,50 +1069,7 @@ async function ilovefeet(imdbId, isSeries = false, season = null, episode = null
|
|||
};
|
||||
}
|
||||
|
||||
async function ilovethighs(watchUrl) {
|
||||
const htmlResponse = await soraFetch(watchUrl);
|
||||
const htmlText = await htmlResponse.text();
|
||||
|
||||
const layoutMatch = htmlText.match(/<script[^>]*src="([^"]*app\/watch\/movie\/[^"]*layout-[^"]*\.js)"[^>]*><\/script><link rel="preload"/);
|
||||
|
||||
if (!layoutMatch || !layoutMatch[1]) {
|
||||
throw new Error("error 1");
|
||||
}
|
||||
|
||||
const beforeLayoutMatch = htmlText.match(/<script[^>]*src="([^"]*\.js)"[^>]*><\/script><script[^>]*src="[^"]*app\/watch\/(movie|tv)\/[^"]*layout-[^"]*\.js"/);
|
||||
|
||||
if (!beforeLayoutMatch || !beforeLayoutMatch[1]) {
|
||||
throw new Error("error 2");
|
||||
}
|
||||
|
||||
let targetUrl = beforeLayoutMatch[1];
|
||||
if (targetUrl.startsWith('/_next/')) {
|
||||
targetUrl = 'https://mapple.uk' + targetUrl;
|
||||
} else if (!targetUrl.startsWith('http')) {
|
||||
targetUrl = 'https://mapple.uk/' + targetUrl;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await soraFetch(targetUrl);
|
||||
const text = await response.text();
|
||||
|
||||
let actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"[^"]*"getStreamUrl/);
|
||||
if (!actionMatch) {
|
||||
actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"/);
|
||||
}
|
||||
if (!actionMatch) {
|
||||
actionMatch = text.match(/"([a-f0-9]{40,})"[^"]*"getStreamUrl/);
|
||||
}
|
||||
|
||||
if (actionMatch && actionMatch[1]) {
|
||||
return actionMatch[1];
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("error 3: " + e);
|
||||
}
|
||||
|
||||
throw new Error("error 4");
|
||||
}
|
||||
|
||||
function wordArrayToUint8Array(wordArray) {
|
||||
const words = wordArray.words;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue