Update anime/anicrush/source.js
This commit is contained in:
@@ -16,8 +16,17 @@ class AniCrush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_nativeFetch(url, method, headers, body) {
|
_nativeFetch(url, method, headers, body) {
|
||||||
const raw = Native.fetch(String(url), method || "GET", JSON.stringify(headers || {}), body == null ? "" : String(body));
|
const raw = Native.fetch(
|
||||||
try { return JSON.parse(raw || "{}"); } catch (e) { return { ok: false, status: 0, headers: {}, body: "" }; }
|
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) {
|
_getText(url, headers) {
|
||||||
@@ -27,12 +36,20 @@ class AniCrush {
|
|||||||
|
|
||||||
_getJson(url, headers) {
|
_getJson(url, headers) {
|
||||||
const res = this._nativeFetch(url, "GET", 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) {
|
_postJson(url, headers, obj) {
|
||||||
const res = this._nativeFetch(url, "POST", headers, JSON.stringify(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) {
|
_safeStr(v) {
|
||||||
@@ -237,6 +254,18 @@ class AniCrush {
|
|||||||
return episodes;
|
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) {
|
findEpisodeServer(episodeOrId, _server) {
|
||||||
let ep = episodeOrId;
|
let ep = episodeOrId;
|
||||||
if (typeof ep === "string") { try { ep = JSON.parse(ep); } catch (e) {} }
|
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 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 linkUrl =
|
const scCandidates =
|
||||||
`${this.apiBase}/shared/v2/episode/sources?_movieId=${encodeURIComponent(id)}` +
|
subOrDub === "dub"
|
||||||
`&ep=${encodeURIComponent(String(num))}&sv=${encodeURIComponent(String(sv))}&sc=${encodeURIComponent(subOrDub)}`;
|
? ["dub", "dubbed", "en", "eng", "2", "1"]
|
||||||
|
: ["sub", "jp", "0", "1"];
|
||||||
|
|
||||||
const json = this._getJson(linkUrl, this._headers());
|
let encryptedIframe = "";
|
||||||
const encryptedIframe = (((json || {}).result || {}).link) ? String(json.result.link) : "";
|
let usedSc = null;
|
||||||
if (!encryptedIframe) throw new Error("Missing encrypted iframe link");
|
|
||||||
|
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 decryptData = null;
|
||||||
let requiredHeaders = null;
|
let requiredHeaders = null;
|
||||||
@@ -295,7 +338,9 @@ class AniCrush {
|
|||||||
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) 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 tracks = decryptData.tracks || [];
|
||||||
const subtitles = tracks
|
const subtitles = tracks
|
||||||
@@ -318,7 +363,8 @@ class AniCrush {
|
|||||||
type: outType,
|
type: outType,
|
||||||
quality: "auto",
|
quality: "auto",
|
||||||
subtitles: subtitles
|
subtitles: subtitles
|
||||||
}]
|
}],
|
||||||
|
_debug: { scUsed: usedSc, sv: sv }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user