Update anime/anicrush/source.js
This commit is contained in:
@@ -43,21 +43,42 @@ class AniCrush {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_postJson(url, headers, obj) {
|
|
||||||
const res = this._nativeFetch(url, "POST", headers, JSON.stringify(obj || {}));
|
|
||||||
try {
|
|
||||||
return JSON.parse(String(res.body || "{}"));
|
|
||||||
} catch (e) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_safeStr(v) {
|
_safeStr(v) {
|
||||||
return typeof v === "string" ? v : (v == null ? "" : String(v));
|
return typeof v === "string" ? v : (v == null ? "" : String(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
_normalizeTitle(t) {
|
_headers() {
|
||||||
return this._safeStr(t)
|
return {
|
||||||
|
"User-Agent": "Mozilla/5.0",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Referer": this.baseUrl + "/",
|
||||||
|
"Origin": this.baseUrl,
|
||||||
|
"X-Site": "anicrush"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_parseQuery(q) {
|
||||||
|
if (typeof q === "string") {
|
||||||
|
const s = q.trim();
|
||||||
|
if (s.startsWith("{") || s.startsWith("[")) {
|
||||||
|
try { return JSON.parse(s); } catch (e) { return { query: s }; }
|
||||||
|
}
|
||||||
|
return { query: s };
|
||||||
|
}
|
||||||
|
return q || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
_normalize(title) {
|
||||||
|
return (this._safeStr(title))
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/(season|cour|part)/g, "")
|
||||||
|
.replace(/\d+(st|nd|rd|th)/g, (m) => m.replace(/st|nd|rd|th/, ""))
|
||||||
|
.replace(/[^a-z0-9]+/g, "")
|
||||||
|
.replace(/(?<!i)ii(?!i)/g, "2");
|
||||||
|
}
|
||||||
|
|
||||||
|
_normalizeTitle(title) {
|
||||||
|
return (this._safeStr(title))
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.replace(/(season|cour|part|uncensored)/g, "")
|
.replace(/(season|cour|part|uncensored)/g, "")
|
||||||
.replace(/\d+(st|nd|rd|th)/g, (m) => m.replace(/st|nd|rd|th/, ""))
|
.replace(/\d+(st|nd|rd|th)/g, (m) => m.replace(/st|nd|rd|th/, ""))
|
||||||
@@ -101,30 +122,9 @@ class AniCrush {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dist = dp[lenA][lenB];
|
const distance = dp[lenA][lenB];
|
||||||
const maxLen = Math.max(lenA, lenB);
|
const maxLen = Math.max(lenA, lenB);
|
||||||
return 1 - dist / maxLen;
|
return 1 - distance / maxLen;
|
||||||
}
|
|
||||||
|
|
||||||
_headers() {
|
|
||||||
return {
|
|
||||||
"User-Agent": "Mozilla/5.0",
|
|
||||||
"Accept": "application/json",
|
|
||||||
"Referer": this.baseUrl + "/",
|
|
||||||
"Origin": this.baseUrl,
|
|
||||||
"X-Site": "anicrush"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseQuery(q) {
|
|
||||||
if (typeof q === "string") {
|
|
||||||
const s = q.trim();
|
|
||||||
if (s.startsWith("{") || s.startsWith("[")) {
|
|
||||||
try { return JSON.parse(s); } catch (e) { return { query: s }; }
|
|
||||||
}
|
|
||||||
return { query: s };
|
|
||||||
}
|
|
||||||
return q || {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
search(query) {
|
search(query) {
|
||||||
@@ -135,18 +135,16 @@ class AniCrush {
|
|||||||
|
|
||||||
const media = query.media || {};
|
const media = query.media || {};
|
||||||
const start = (media.startDate || {});
|
const start = (media.startDate || {});
|
||||||
const wantYear = start.year || 0;
|
const targetNormJP = this._normalize(media.romajiTitle);
|
||||||
const wantMonth = start.month || 0;
|
const targetNorm = media.englishTitle ? this._normalize(media.englishTitle) : targetNormJP;
|
||||||
|
|
||||||
const targetNormJP = this._normalizeTitle(media.romajiTitle);
|
|
||||||
const targetNorm = media.englishTitle ? this._normalizeTitle(media.englishTitle) : targetNormJP;
|
|
||||||
|
|
||||||
const url = `${this.apiBase}/shared/v2/movie/list?keyword=${encodeURIComponent(q)}&limit=48&page=1`;
|
const url = `${this.apiBase}/shared/v2/movie/list?keyword=${encodeURIComponent(q)}&limit=48&page=1`;
|
||||||
const json = this._getJson(url, this._headers());
|
const json = this._getJson(url, this._headers());
|
||||||
const list = (((json || {}).result || {}).movies) || [];
|
|
||||||
if (!Array.isArray(list) || !list.length) return [];
|
|
||||||
|
|
||||||
let matches = list.map((movie) => {
|
const movies = (((json || {}).result || {}).movies) || [];
|
||||||
|
if (!Array.isArray(movies) || !movies.length) return [];
|
||||||
|
|
||||||
|
let matches = movies.map((movie) => {
|
||||||
const id = movie && movie.id != null ? String(movie.id) : "";
|
const id = movie && movie.id != null ? String(movie.id) : "";
|
||||||
const slug = movie && movie.slug ? String(movie.slug) : "";
|
const slug = movie && movie.slug ? String(movie.slug) : "";
|
||||||
if (!id || !slug) return null;
|
if (!id || !slug) return null;
|
||||||
@@ -157,11 +155,11 @@ class AniCrush {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
slug,
|
pageUrl: slug,
|
||||||
title,
|
title,
|
||||||
titleJP,
|
titleJP,
|
||||||
normTitle: this._normalizeTitle(title),
|
normTitleJP: this._normalize(titleJP),
|
||||||
normTitleJP: this._normalizeTitle(titleJP),
|
normTitle: this._normalize(title),
|
||||||
dub: !!(movie && movie.has_dub),
|
dub: !!(movie && movie.has_dub),
|
||||||
startDate: this._normalizeDate(movie && movie.aired_from ? String(movie.aired_from) : "")
|
startDate: this._normalizeDate(movie && movie.aired_from ? String(movie.aired_from) : "")
|
||||||
};
|
};
|
||||||
@@ -169,55 +167,90 @@ class AniCrush {
|
|||||||
|
|
||||||
if (query.dub) matches = matches.filter(m => m.dub);
|
if (query.dub) matches = matches.filter(m => m.dub);
|
||||||
|
|
||||||
let filtered = matches;
|
let filtered = matches.filter(m => {
|
||||||
|
const titleMatch = (m.normTitle === targetNorm) || (m.normTitleJP === targetNormJP);
|
||||||
if (wantYear) {
|
const dateMatch =
|
||||||
filtered = matches.filter(m => {
|
(m.startDate && m.startDate.year === start.year) &&
|
||||||
const tMatch = (m.normTitle === targetNorm) || (m.normTitleJP === targetNormJP);
|
(m.startDate && m.startDate.month === start.month);
|
||||||
const d = m.startDate || {};
|
return titleMatch && dateMatch;
|
||||||
const dMatch = wantMonth ? ((d.year === wantYear) && (d.month === wantMonth)) : (d.year === wantYear);
|
|
||||||
return tMatch && dMatch;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!filtered.length) {
|
if (!filtered.length) {
|
||||||
filtered = matches.filter(m => {
|
filtered = matches.filter(m => {
|
||||||
const a = m.normTitle;
|
const titleMatch = (m.normTitle === targetNorm) || (m.normTitleJP === targetNormJP);
|
||||||
const b = targetNorm;
|
const dateMatch = (m.startDate && m.startDate.year === start.year);
|
||||||
const aj = m.normTitleJP;
|
return titleMatch && dateMatch;
|
||||||
const bj = targetNormJP;
|
|
||||||
|
|
||||||
const fuzzy =
|
|
||||||
(a && b && (a.includes(b) || b.includes(a) || this._levSim(a, b) > 0.72)) ||
|
|
||||||
(aj && bj && (aj.includes(bj) || bj.includes(aj) || this._levSim(aj, bj) > 0.72));
|
|
||||||
|
|
||||||
const d = m.startDate || {};
|
|
||||||
const dMatch = wantMonth ? ((d.year === wantYear) && (d.month === wantMonth)) : (d.year === wantYear);
|
|
||||||
return fuzzy && dMatch;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
if (!filtered.length) {
|
||||||
|
filtered = matches.filter(m => {
|
||||||
|
const titleMatch =
|
||||||
|
m.normTitle.includes(targetNorm) ||
|
||||||
|
m.normTitleJP.includes(targetNormJP) ||
|
||||||
|
targetNorm.includes(m.normTitle) ||
|
||||||
|
targetNormJP.includes(m.normTitleJP) ||
|
||||||
|
this._levSim(m.normTitle, targetNorm) > 0.7 ||
|
||||||
|
this._levSim(m.normTitleJP, targetNormJP) > 0.7;
|
||||||
|
|
||||||
|
const dateMatch =
|
||||||
|
(m.startDate && m.startDate.year === start.year) &&
|
||||||
|
(m.startDate && m.startDate.month === start.month);
|
||||||
|
|
||||||
|
return titleMatch && dateMatch;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filtered.length) {
|
||||||
|
filtered = matches.filter(m => {
|
||||||
|
const titleMatch =
|
||||||
|
m.normTitle.includes(targetNorm) ||
|
||||||
|
m.normTitleJP.includes(targetNormJP) ||
|
||||||
|
targetNorm.includes(m.normTitle) ||
|
||||||
|
targetNormJP.includes(m.normTitleJP) ||
|
||||||
|
this._levSim(m.normTitle, targetNorm) > 0.7 ||
|
||||||
|
this._levSim(m.normTitleJP, targetNormJP) > 0.7;
|
||||||
|
|
||||||
|
const dateMatch = (m.startDate && m.startDate.year === start.year);
|
||||||
|
return titleMatch && dateMatch;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let results = filtered.map(m => ({
|
||||||
|
id: `${m.id}/${query.dub ? "dub" : "sub"}`,
|
||||||
|
title: m.title,
|
||||||
|
url: `${this.baseUrl}/detail/${m.pageUrl}.${m.id}`,
|
||||||
|
subOrDub: query.dub ? "dub" : "sub"
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!media.startDate || !media.startDate.year) {
|
||||||
const qn = this._normalizeTitle(q);
|
const qn = this._normalizeTitle(q);
|
||||||
filtered = matches.filter(m => {
|
filtered = matches.filter(m => {
|
||||||
const a = this._normalizeTitle(m.title);
|
const a = this._normalizeTitle(m.title);
|
||||||
const aj = this._normalizeTitle(m.titleJP);
|
const aj = this._normalizeTitle(m.titleJP);
|
||||||
return (a === qn) || (aj === qn) || a.includes(qn) || aj.includes(qn) || qn.includes(a) || qn.includes(aj);
|
return (
|
||||||
|
a === qn || aj === qn ||
|
||||||
|
a.includes(qn) || aj.includes(qn) ||
|
||||||
|
qn.includes(a) || qn.includes(aj)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
filtered.sort((x, y) => {
|
filtered.sort((a, b) => {
|
||||||
const A = this._normalizeTitle(x.title);
|
const A = this._normalizeTitle(a.title);
|
||||||
const B = this._normalizeTitle(y.title);
|
const B = this._normalizeTitle(b.title);
|
||||||
if (A.length !== B.length) return A.length - B.length;
|
if (A.length !== B.length) return A.length - B.length;
|
||||||
return A.localeCompare(B);
|
return A.localeCompare(B);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
results = filtered.map(m => ({
|
||||||
|
id: `${m.id}/${query.dub ? "dub" : "sub"}`,
|
||||||
|
title: m.title,
|
||||||
|
url: `${this.baseUrl}/detail/${m.pageUrl}.${m.id}`,
|
||||||
|
subOrDub: query.dub ? "dub" : "sub"
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const subOrDub = query.dub ? "dub" : "sub";
|
return results;
|
||||||
return filtered.map(m => ({
|
|
||||||
id: `${m.id}/${subOrDub}`,
|
|
||||||
title: m.title,
|
|
||||||
url: `${this.baseUrl}/detail/${m.slug}.${m.id}`,
|
|
||||||
subOrDub
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findEpisodes(Id) {
|
findEpisodes(Id) {
|
||||||
@@ -228,19 +261,17 @@ class AniCrush {
|
|||||||
|
|
||||||
const url = `${this.apiBase}/shared/v2/episode/list?_movieId=${encodeURIComponent(id)}`;
|
const url = `${this.apiBase}/shared/v2/episode/list?_movieId=${encodeURIComponent(id)}`;
|
||||||
const epJson = this._getJson(url, this._headers());
|
const epJson = this._getJson(url, this._headers());
|
||||||
const groups = (epJson && epJson.result) ? epJson.result : {};
|
const episodeGroups = (epJson && epJson.result) ? epJson.result : {};
|
||||||
|
|
||||||
const episodes = [];
|
const episodes = [];
|
||||||
|
const keys = Object.keys(episodeGroups || {});
|
||||||
const keys = Object.keys(groups || {});
|
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
const group = groups[keys[i]];
|
const group = episodeGroups[keys[i]];
|
||||||
if (!Array.isArray(group)) continue;
|
if (!Array.isArray(group)) continue;
|
||||||
|
|
||||||
for (let j = 0; j < group.length; j++) {
|
for (let j = 0; j < group.length; j++) {
|
||||||
const ep = group[j] || {};
|
const ep = group[j] || {};
|
||||||
const num = Number(ep.number);
|
const num = Number(ep.number);
|
||||||
if (!Number.isFinite(num)) continue;
|
if (!Number.isFinite(num)) continue;
|
||||||
|
|
||||||
episodes.push({
|
episodes.push({
|
||||||
id: `${id}/${subOrDub}`,
|
id: `${id}/${subOrDub}`,
|
||||||
number: num,
|
number: num,
|
||||||
@@ -254,33 +285,23 @@ class AniCrush {
|
|||||||
return episodes;
|
return episodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getEpisodeSourcesLink(movieId, epNumber, sv, sc) {
|
findEpisodeServer(episode, _server) {
|
||||||
const linkUrl =
|
if (typeof episode === "string") {
|
||||||
`${this.apiBase}/shared/v2/episode/sources?_movieId=${encodeURIComponent(movieId)}` +
|
try { episode = JSON.parse(episode); } catch (e) {}
|
||||||
`&ep=${encodeURIComponent(String(epNumber))}` +
|
|
||||||
`&sv=${encodeURIComponent(String(sv))}` +
|
|
||||||
`&sc=${encodeURIComponent(String(sc))}`;
|
|
||||||
|
|
||||||
const json = this._getJson(linkUrl, this._headers());
|
|
||||||
const link = (((json || {}).result || {}).link) ? String(json.result.link) : "";
|
|
||||||
return { json, link, linkUrl };
|
|
||||||
}
|
}
|
||||||
|
episode = episode || {};
|
||||||
|
|
||||||
findEpisodeServer(episodeOrId, _server) {
|
const parts = String(episode.id || "").split("/");
|
||||||
let ep = episodeOrId;
|
|
||||||
if (typeof ep === "string") { try { ep = JSON.parse(ep); } catch (e) {} }
|
|
||||||
ep = ep || {};
|
|
||||||
|
|
||||||
const parts = String(ep.id || "").split("/");
|
|
||||||
const id = parts[0];
|
const id = parts[0];
|
||||||
const subOrDub = parts[1] || "sub";
|
const subOrDub = parts[1] || "sub";
|
||||||
if (!id) throw new Error("Missing id");
|
if (!id) throw new Error("Missing id");
|
||||||
|
|
||||||
const num = Number(ep.number);
|
const epNum = Number(episode.number);
|
||||||
if (!Number.isFinite(num)) throw new Error("Missing episode number");
|
if (!Number.isFinite(epNum)) throw new Error("Missing episode number");
|
||||||
|
|
||||||
let server = String(_server || "").trim();
|
let server = String(_server || "").trim();
|
||||||
if (!server || server === "default") server = "Southcloud-1";
|
if (!server || server === "default") server = "Southcloud-1";
|
||||||
|
|
||||||
if (server === "HD-1") server = "Southcloud-1";
|
if (server === "HD-1") server = "Southcloud-1";
|
||||||
if (server === "HD-2") server = "Southcloud-2";
|
if (server === "HD-2") server = "Southcloud-2";
|
||||||
if (server === "HD-3") server = "Southcloud-3";
|
if (server === "HD-3") server = "Southcloud-3";
|
||||||
@@ -288,26 +309,16 @@ class AniCrush {
|
|||||||
const serverMap = { "Southcloud-1": 4, "Southcloud-2": 1, "Southcloud-3": 6 };
|
const serverMap = { "Southcloud-1": 4, "Southcloud-2": 1, "Southcloud-3": 6 };
|
||||||
const sv = serverMap[server] != null ? serverMap[server] : 4;
|
const sv = serverMap[server] != null ? serverMap[server] : 4;
|
||||||
|
|
||||||
const scCandidates =
|
const encryptedLinkUrl =
|
||||||
subOrDub === "dub"
|
`${this.apiBase}/shared/v2/episode/sources?_movieId=${encodeURIComponent(id)}` +
|
||||||
? ["dub", "dubbed", "en", "eng", "2", "1"]
|
`&ep=${encodeURIComponent(String(epNum))}` +
|
||||||
: ["sub", "jp", "0", "1"];
|
`&sv=${encodeURIComponent(String(sv))}` +
|
||||||
|
`&sc=${encodeURIComponent(String(subOrDub))}`;
|
||||||
let encryptedIframe = "";
|
|
||||||
let usedSc = null;
|
|
||||||
|
|
||||||
for (let i = 0; i < scCandidates.length; i++) {
|
|
||||||
const sc = scCandidates[i];
|
|
||||||
const r = this._getEpisodeSourcesLink(id, num, sv, sc);
|
|
||||||
if (r.link) {
|
|
||||||
encryptedIframe = r.link;
|
|
||||||
usedSc = sc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const json = this._getJson(encryptedLinkUrl, this._headers());
|
||||||
|
const encryptedIframe = (((json || {}).result || {}).link) ? String(json.result.link) : "";
|
||||||
if (!encryptedIframe) {
|
if (!encryptedIframe) {
|
||||||
throw new Error(`Missing encrypted iframe link (movieId=${id} ep=${num} server=${server} sv=${sv} scTried=${scCandidates.join(",")})`);
|
throw new Error(`Missing encrypted iframe link (server=${server} sv=${sv} sc=${subOrDub})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let decryptData = null;
|
let decryptData = null;
|
||||||
@@ -326,24 +337,22 @@ class AniCrush {
|
|||||||
requiredHeaders = {
|
requiredHeaders = {
|
||||||
Referer: "https://megacloud.club/",
|
Referer: "https://megacloud.club/",
|
||||||
Origin: "https://megacloud.club",
|
Origin: "https://megacloud.club",
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
|
"User-Agent":
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
|
||||||
"X-Requested-With": "XMLHttpRequest"
|
"X-Requested-With": "XMLHttpRequest"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decryptData) throw new Error("No video sources");
|
if (!decryptData || !decryptData.sources) throw new Error("No video sources from any decrypter");
|
||||||
|
|
||||||
const sources = decryptData.sources || [];
|
const sources = decryptData.sources || [];
|
||||||
const streamSource =
|
const streamSource =
|
||||||
sources.find((s) => s && s.type === "hls") ||
|
sources.find((s) => s && s.type === "hls") ||
|
||||||
sources.find((s) => s && s.type === "mp4");
|
sources.find((s) => s && s.type === "mp4");
|
||||||
|
|
||||||
if (!streamSource || !streamSource.file) {
|
if (!streamSource || !streamSource.file) throw new Error("No valid stream file found");
|
||||||
throw new Error(`No valid stream file found (scUsed=${usedSc || "none"})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const tracks = decryptData.tracks || [];
|
const subtitles = (decryptData.tracks || [])
|
||||||
const subtitles = tracks
|
|
||||||
.filter((t) => t && t.kind === "captions" && t.file)
|
.filter((t) => t && t.kind === "captions" && t.file)
|
||||||
.map((track, index) => ({
|
.map((track, index) => ({
|
||||||
id: `sub-${index}`,
|
id: `sub-${index}`,
|
||||||
@@ -352,19 +361,19 @@ class AniCrush {
|
|||||||
isDefault: !!track.default
|
isDefault: !!track.default
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const st = String(streamSource.type || "");
|
const outType = (String(streamSource.type || "") === "hls") ? "m3u8" : "mp4";
|
||||||
const outType = (st === "hls" || st === "m3u8") ? "m3u8" : "mp4";
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
server: server,
|
server: server,
|
||||||
headers: requiredHeaders || {},
|
headers: requiredHeaders || {},
|
||||||
videoSources: [{
|
videoSources: [
|
||||||
|
{
|
||||||
url: streamSource.file,
|
url: streamSource.file,
|
||||||
type: outType,
|
type: outType,
|
||||||
quality: "auto",
|
quality: "auto",
|
||||||
subtitles: subtitles
|
subtitles
|
||||||
}],
|
}
|
||||||
_debug: { scUsed: usedSc, sv: sv }
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,13 +391,14 @@ class AniCrush {
|
|||||||
"X-Requested-With": "XMLHttpRequest",
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
Referer: baseDomain,
|
Referer: baseDomain,
|
||||||
Origin: `${protocol}://${host}`,
|
Origin: `${protocol}://${host}`,
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
|
"User-Agent":
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = this._getText(embedUrl, headers);
|
const html = this._getText(embedUrl, headers);
|
||||||
|
|
||||||
const fileIdMatch = html.match(/<title>\s*File\s+#([a-zA-Z0-9]+)\s*-/i);
|
const fileIdMatch = html.match(/<title>\s*File\s+#([a-zA-Z0-9]+)\s*-/i);
|
||||||
if (!fileIdMatch) throw new Error("file_id not found");
|
if (!fileIdMatch) throw new Error("file_id not found in embed page");
|
||||||
const fileId = fileIdMatch[1];
|
const fileId = fileIdMatch[1];
|
||||||
|
|
||||||
let nonce = null;
|
let nonce = null;
|
||||||
@@ -403,7 +413,10 @@ class AniCrush {
|
|||||||
}
|
}
|
||||||
if (!nonce) throw new Error("nonce not found");
|
if (!nonce) throw new Error("nonce not found");
|
||||||
|
|
||||||
const sourcesJson = this._getJson(`${baseDomain}embed-2/v3/e-1/getSources?id=${fileId}&_k=${nonce}`, headers);
|
const sourcesJson = this._getJson(
|
||||||
|
`${baseDomain}embed-2/v3/e-1/getSources?id=${fileId}&_k=${nonce}`,
|
||||||
|
headers
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sources: sourcesJson.sources || [],
|
sources: sourcesJson.sources || [],
|
||||||
|
|||||||
Reference in New Issue
Block a user