mirror of
https://git.luna-app.eu/50n50/sources
synced 2026-01-12 01:18:11 +01:00
Add anicrush/anicrush.js
This commit is contained in:
parent
a32c786156
commit
c686cfbab3
1 changed files with 282 additions and 0 deletions
282
anicrush/anicrush.js
Normal file
282
anicrush/anicrush.js
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
async function searchResults(keyword) {
|
||||
const results = [];
|
||||
|
||||
const headers = {
|
||||
"Host": "api.anicrush.to",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||
"x-site": "anicrush",
|
||||
"Origin": "https://anicrush.to",
|
||||
"Connection": "keep-alive",
|
||||
"Referer": "https://anicrush.to/",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-site",
|
||||
"TE": "trailers"
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetchv2("https://api.anicrush.to/shared/v2/movie/list?keyword=" + encodeURIComponent(keyword) + "&limit=24&page=1", headers);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status && data.result && data.result.movies) {
|
||||
for (const movie of data.result.movies) {
|
||||
results.push({
|
||||
title: movie.name_english || movie.name,
|
||||
image: getImage(movie.poster_path),
|
||||
href: "/watch/" + movie.slug + "." + movie.id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(results);
|
||||
} catch (err) {
|
||||
return JSON.stringify([{
|
||||
title: "Error",
|
||||
image: "Error",
|
||||
href: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractDetails(url) {
|
||||
const id = url.split('.').pop();
|
||||
|
||||
const headers = {
|
||||
"Host": "api.anicrush.to",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||
"x-site": "anicrush",
|
||||
"Origin": "https://anicrush.to",
|
||||
"Connection": "keep-alive",
|
||||
"Referer": "https://anicrush.to/",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-site",
|
||||
"TE": "trailers"
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetchv2(`https://api.anicrush.to/shared/v2/movie/getById/${id}`, headers);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status && data.result) {
|
||||
const result = data.result;
|
||||
const description = result.overview || "N/A";
|
||||
const aliases = result.name_synonyms || "N/A";
|
||||
const airdate = result.aired_from || "N/A";
|
||||
|
||||
return JSON.stringify([{
|
||||
description: description,
|
||||
aliases: aliases,
|
||||
airdate: airdate
|
||||
}]);
|
||||
} else {
|
||||
return JSON.stringify([{
|
||||
description: "Error",
|
||||
aliases: "Error",
|
||||
airdate: "Error"
|
||||
}]);
|
||||
}
|
||||
} catch (err) {
|
||||
return JSON.stringify([{
|
||||
description: "Error",
|
||||
aliases: "Error",
|
||||
airdate: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractEpisodes(url) {
|
||||
const results = [];
|
||||
const id = url.split('.').pop();
|
||||
|
||||
const headers = {
|
||||
"Host": "api.anicrush.to",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"x-site": "anicrush",
|
||||
"Origin": "https://anicrush.to",
|
||||
"Connection": "keep-alive",
|
||||
"Referer": "https://anicrush.to/",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-site",
|
||||
"TE": "trailers"
|
||||
};
|
||||
|
||||
try {
|
||||
const url = `https://api.anicrush.to/shared/v2/episode/list?_movieId=${id}`;
|
||||
|
||||
const response = await fetchv2(url, headers);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status && data.result) {
|
||||
const seasons = Object.keys(data.result);
|
||||
for (const seasonKey of seasons) {
|
||||
const season = data.result[seasonKey];
|
||||
const isMovie = seasonKey === "001 - 001";
|
||||
for (const ep of season) {
|
||||
const href = isMovie ? `?_movieId=${id}&ep=1` : `?_movieId=${id}&ep=${ep.number}`;
|
||||
results.push({
|
||||
href: href,
|
||||
number: ep.number
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(results);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return JSON.stringify([{ id: "Error", href: "Error", number: "Error", title: "Error" }]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractStreamUrl(ID) {
|
||||
const headers = {
|
||||
"Host": "api.anicrush.to",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"x-site": "anicrush",
|
||||
"Origin": "https://anicrush.to",
|
||||
"Connection": "keep-alive",
|
||||
"Referer": "https://anicrush.to/",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-site",
|
||||
"TE": "trailers"
|
||||
};
|
||||
|
||||
const headersTwo = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:146.0) Gecko/20100101 Firefox/146.0",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Referer": "https://hianime.to/"
|
||||
};
|
||||
|
||||
try {
|
||||
const url = `https://api.anicrush.to/shared/v2/episode/servers${ID}`;
|
||||
|
||||
const serversResp = await fetchv2(url, headers);
|
||||
const serversJson = await serversResp.json();
|
||||
console.log(JSON.stringify(serversJson));
|
||||
|
||||
const subServer = serversJson.result?.sub?.[0];
|
||||
const dubServer = serversJson.result?.dub?.[0];
|
||||
const rawServer = serversJson.result?.raw?.[0];
|
||||
|
||||
const subServerId = subServer?.server;
|
||||
const dubServerId = dubServer?.server;
|
||||
const rawServerId = rawServer?.server;
|
||||
|
||||
const processServer = async (serverId, title) => {
|
||||
try {
|
||||
const sourcesResp = await fetchv2(`https://api.anicrush.to/shared/v2/episode/sources${ID}&sv=${serverId}&sc=${title.toLowerCase()}`, headers);
|
||||
const sourcesJson = await sourcesResp.json();
|
||||
const iframeUrl = sourcesJson.result?.link;
|
||||
|
||||
if (!iframeUrl) return null;
|
||||
|
||||
const iframeResp = await fetchv2(iframeUrl, headersTwo);
|
||||
const iframeHtml = await iframeResp.text();
|
||||
|
||||
const videoTagMatch = iframeHtml.match(/data-id="([^"]+)"/);
|
||||
if (!videoTagMatch) return null;
|
||||
const fileId = videoTagMatch[1];
|
||||
|
||||
const nonceMatch = iframeHtml.match(/\b[a-zA-Z0-9]{48}\b/) ||
|
||||
iframeHtml.match(/\b([a-zA-Z0-9]{16})\b.*?\b([a-zA-Z0-9]{16})\b.*?\b([a-zA-Z0-9]{16})\b/);
|
||||
if (!nonceMatch) return null;
|
||||
|
||||
const nonce = nonceMatch.length === 4 ?
|
||||
nonceMatch[1] + nonceMatch[2] + nonceMatch[3] :
|
||||
nonceMatch[0];
|
||||
|
||||
const urlParts = iframeUrl.split('/');
|
||||
const protocol = iframeUrl.startsWith('https') ? 'https:' : 'http:';
|
||||
const hostname = urlParts[2];
|
||||
const defaultDomain = `${protocol}//${hostname}/`;
|
||||
|
||||
const getSourcesUrl = `${defaultDomain}embed-2/v3/e-1/getSources?id=${fileId}&_k=${nonce}`;
|
||||
const getSourcesResp = await fetchv2(getSourcesUrl, headersTwo);
|
||||
const getSourcesJson = await getSourcesResp.json();
|
||||
const videoUrl = getSourcesJson.sources?.[0]?.file || "";
|
||||
if (!videoUrl) return null;
|
||||
|
||||
const streamHeaders = {
|
||||
"Referer": defaultDomain,
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36"
|
||||
};
|
||||
|
||||
return {
|
||||
title: title,
|
||||
streamUrl: videoUrl,
|
||||
headers: streamHeaders,
|
||||
sourcesData: getSourcesJson
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(`${title} failed:`, e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const serverPromises = [];
|
||||
if (subServerId) serverPromises.push(processServer(subServerId, "SUB"));
|
||||
if (dubServerId) serverPromises.push(processServer(dubServerId, "DUB"));
|
||||
if (rawServerId) serverPromises.push(processServer(rawServerId, "RAW"));
|
||||
|
||||
const results = await Promise.all(serverPromises);
|
||||
const streams = results.filter(r => r !== null);
|
||||
|
||||
if (streams.length === 0) {
|
||||
return "https://error.org/";
|
||||
}
|
||||
|
||||
const englishTrack = streams[0].sourcesData.tracks?.find(t => t.kind === "captions" && t.label === "English");
|
||||
const subtitle = englishTrack ? englishTrack.file : "";
|
||||
|
||||
const finalStreams = streams.map(s => ({
|
||||
title: s.title,
|
||||
streamUrl: s.streamUrl,
|
||||
headers: s.headers
|
||||
}));
|
||||
console.log(JSON.stringify({
|
||||
streams: finalStreams,
|
||||
subtitle: subtitle
|
||||
}));
|
||||
return JSON.stringify({
|
||||
streams: finalStreams,
|
||||
subtitles: subtitle
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return "https://error.oraag/";
|
||||
}
|
||||
}
|
||||
|
||||
function getImage(path, type = "poster") {
|
||||
const baseUrl = "https://static.gniyonna.com/media/poster";
|
||||
const hashWithExt = path.split('/')[3];
|
||||
const hash = hashWithExt.split('.')[0];
|
||||
|
||||
let reversedHash = '';
|
||||
for (let i = hash.length - 1; i >= 0; i--) {
|
||||
reversedHash += hash[i];
|
||||
}
|
||||
|
||||
const ext = hashWithExt.split('.').pop();
|
||||
const size = type === "poster" ? "300x400" : "900x600";
|
||||
const imageUrl = `${baseUrl}/${size}/100/${reversedHash}.${ext}`;
|
||||
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue