updates and new extensions

This commit is contained in:
2026-01-05 04:46:26 +01:00
parent 5ee2bde49a
commit 83c51a82da
9 changed files with 1500 additions and 129 deletions

View File

@@ -1,7 +1,7 @@
class HiAnime {
constructor() {
this.type = "anime-board";
this.version = "1.0"
this.version = "1.1"
this.baseUrl = "https://hianime.to";
}
@@ -91,70 +91,74 @@ class HiAnime {
return episodes;
}
async findEpisodeServer(episode, _server) {
const [id, subOrDub] = episode.id.split("/");
let serverName = _server !== "default" ? _server : "HD-1";
async findEpisodeServer(episode, _server, category = "sub") {
const id = episode.id;
const subOrDub = category; // backend manda sub | dub
if (_server === "HD-1" || _server === "HD-2" || _server === "HD-3") {
const serverJson = await fetch(`${this.baseUrl}/ajax/v2/episode/servers?episodeId=${id}`, {
headers: { "X-Requested-With": "XMLHttpRequest" }
}).then(res => res.json());
const serverName = _server !== "default" ? _server : "HD-1";
if (serverName === "HD-1" || serverName === "HD-2" || serverName === "HD-3") {
const serverJson = await fetch(
`${this.baseUrl}/ajax/v2/episode/servers?episodeId=${id}`,
{ headers: { "X-Requested-With": "XMLHttpRequest" } }
).then(res => res.json());
const serverHtml = serverJson.html;
const regex = new RegExp(
`<div[^>]*class="item server-item"[^>]*data-type="${subOrDub}"[^>]*data-id="(\\d+)"[^>]*>\\s*<a[^>]*>\\s*${serverName}\\s*</a>`,
"i"
);
const match = regex.exec(serverHtml);
if (!match) throw new Error(`Server "${serverName}" (${subOrDub}) not found`);
if (!match)
throw new Error(`Server "${serverName}" (${subOrDub}) not found`);
const serverId = match[1];
const sourcesJson = await fetch(`${this.baseUrl}/ajax/v2/episode/sources?id=${serverId}`, {
headers: { "X-Requested-With": "XMLHttpRequest" }
}).then(res => res.json());
const sourcesJson = await fetch(
`${this.baseUrl}/ajax/v2/episode/sources?id=${serverId}`,
{ headers: { "X-Requested-With": "XMLHttpRequest" } }
).then(res => res.json());
let decryptData = null;
let decryptData;
let requiredHeaders = {};
try {
// Pass true to get headers back
decryptData = await this.extractMegaCloud(sourcesJson.link, true);
if (decryptData && decryptData.headersProvided) {
if (decryptData?.headersProvided) {
requiredHeaders = decryptData.headersProvided;
}
} catch (err) {
console.warn("Primary decrypter failed:", err);
} catch (e) {
console.warn("Primary decrypter failed:", e);
}
if (!decryptData) {
console.warn("Primary decrypter failed — trying ShadeOfChaos fallback...");
const fallbackRes = await fetch(
`https://ac-api.ofchaos.com/api/anime/embed/convert/v2?embedUrl=${encodeURIComponent(sourcesJson.link)}`
);
decryptData = await fallbackRes.json();
// CRITICAL: Fallback headers must mimic the browser behavior expected by the provider
// These MUST be used by a server-side proxy; the browser player cannot set them.
requiredHeaders = {
"Referer": "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",
"X-Requested-With": "XMLHttpRequest"
Referer: "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",
"X-Requested-With": "XMLHttpRequest",
};
}
const streamSource =
decryptData.sources.find((s) => s.type === "hls") ||
decryptData.sources.find((s) => s.type === "mp4");
decryptData.sources.find(s => s.type === "hls") ||
decryptData.sources.find(s => s.type === "mp4");
if (!streamSource?.file) throw new Error("No valid stream file found");
if (!streamSource?.file)
throw new Error("No valid stream file found");
const subtitles = (decryptData.tracks || [])
.filter((t) => t.kind === "captions")
.map((track, index) => ({
id: `sub-${index}`,
.filter(t => t.kind === "captions")
.map((track, i) => ({
id: `sub-${i}`,
language: track.label || "Unknown",
url: track.file,
isDefault: !!track.default,
@@ -163,18 +167,23 @@ class HiAnime {
return {
server: serverName,
headers: requiredHeaders,
videoSources: [{
url: streamSource.file,
type: streamSource.type === "hls" ? "m3u8" : "mp4",
quality: "auto",
subtitles
}]
videoSources: [
{
url: streamSource.file,
type: streamSource.type === "hls" ? "m3u8" : "mp4",
quality: "auto",
subtitles,
subOrDub: category,
},
],
};
}
else if (_server === "HD-4") {
// Implementation for HD-4 if needed
return null;
if (serverName === "HD-4") {
throw new Error("HD-4 not implemented");
}
throw new Error(`Unknown server ${serverName}`);
}
safeString(str) {