Update anime/anicrush/source.js

This commit is contained in:
2025-12-26 00:29:16 +01:00
parent 3dfd123c5b
commit 5bd2d259fb

View File

@@ -16,8 +16,17 @@ class AniCrush {
}
_nativeFetch(url, method, headers, body) {
const raw = Native.fetch(String(url), method || "GET", JSON.stringify(headers || {}), body == null ? "" : String(body));
try { return JSON.parse(raw || "{}"); } catch (e) { return { ok: false, status: 0, headers: {}, body: "" }; }
const raw = Native.fetch(
String(url),
method || "GET",
JSON.stringify(headers || {}),
body == null ? "" : String(body)
);
try {
return JSON.parse(raw || "{}");
} catch (e) {
return { ok: false, status: 0, headers: {}, body: "" };
}
}
_getText(url, headers) {
@@ -27,12 +36,20 @@ class AniCrush {
_getJson(url, headers) {
const res = this._nativeFetch(url, "GET", headers, "");
try { return JSON.parse(String(res.body || "{}")); } catch (e) { return {}; }
try {
return JSON.parse(String(res.body || "{}"));
} catch (e) {
return {};
}
}
_postJson(url, headers, obj) {
const res = this._nativeFetch(url, "POST", headers, JSON.stringify(obj || {}));
try { return JSON.parse(String(res.body || "{}")); } catch (e) { return {}; }
try {
return JSON.parse(String(res.body || "{}"));
} catch (e) {
return {};
}
}
_safeStr(v) {
@@ -237,6 +254,18 @@ class AniCrush {
return episodes;
}
_getEpisodeSourcesLink(movieId, epNumber, sv, sc) {
const linkUrl =
`${this.apiBase}/shared/v2/episode/sources?_movieId=${encodeURIComponent(movieId)}` +
`&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 };
}
findEpisodeServer(episodeOrId, _server) {
let ep = episodeOrId;
if (typeof ep === "string") { try { ep = JSON.parse(ep); } catch (e) {} }
@@ -259,13 +288,27 @@ class AniCrush {
const serverMap = { "Southcloud-1": 4, "Southcloud-2": 1, "Southcloud-3": 6 };
const sv = serverMap[server] != null ? serverMap[server] : 4;
const linkUrl =
`${this.apiBase}/shared/v2/episode/sources?_movieId=${encodeURIComponent(id)}` +
`&ep=${encodeURIComponent(String(num))}&sv=${encodeURIComponent(String(sv))}&sc=${encodeURIComponent(subOrDub)}`;
const scCandidates =
subOrDub === "dub"
? ["dub", "dubbed", "en", "eng", "2", "1"]
: ["sub", "jp", "0", "1"];
const json = this._getJson(linkUrl, this._headers());
const encryptedIframe = (((json || {}).result || {}).link) ? String(json.result.link) : "";
if (!encryptedIframe) throw new Error("Missing encrypted iframe link");
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;
}
}
if (!encryptedIframe) {
throw new Error(`Missing encrypted iframe link (movieId=${id} ep=${num} server=${server} sv=${sv} scTried=${scCandidates.join(",")})`);
}
let decryptData = null;
let requiredHeaders = null;
@@ -295,7 +338,9 @@ class AniCrush {
sources.find((s) => s && s.type === "hls") ||
sources.find((s) => s && s.type === "mp4");
if (!streamSource || !streamSource.file) throw new Error("No valid stream file found");
if (!streamSource || !streamSource.file) {
throw new Error(`No valid stream file found (scUsed=${usedSc || "none"})`);
}
const tracks = decryptData.tracks || [];
const subtitles = tracks
@@ -318,7 +363,8 @@ class AniCrush {
type: outType,
quality: "auto",
subtitles: subtitles
}]
}],
_debug: { scUsed: usedSc, sv: sv }
};
}