This commit is contained in:
aka paul
2026-04-23 22:07:29 +02:00
parent 5a8c5cbb62
commit cbabd0643e
4 changed files with 120 additions and 186 deletions
+59 -90
View File
@@ -114,6 +114,11 @@ async function extractEpisodes(url) {
} }
async function extractStreamUrl(url) { async function extractStreamUrl(url) {
const headers = {
"Referer": "https://anikai.to/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
};
try { try {
const tokenMatch = url.match(/token=([^&]+)/); const tokenMatch = url.match(/token=([^&]+)/);
if (tokenMatch && tokenMatch[1]) { if (tokenMatch && tokenMatch[1]) {
@@ -124,8 +129,7 @@ async function extractStreamUrl(url) {
url = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`); url = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
} }
const fetchUrl = `${url}`; const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(fetchUrl));
const text = await response.text(); const text = await response.text();
let ajaxResultHtml = ""; let ajaxResultHtml = "";
@@ -141,25 +145,15 @@ async function extractStreamUrl(url) {
const subRegex = /<div class="server-items lang-group" data-id="sub"[^>]*>([\s\S]*?)<\/div>/; const subRegex = /<div class="server-items lang-group" data-id="sub"[^>]*>([\s\S]*?)<\/div>/;
const softsubRegex = /<div class="server-items lang-group" data-id="softsub"[^>]*>([\s\S]*?)<\/div>/; const softsubRegex = /<div class="server-items lang-group" data-id="softsub"[^>]*>([\s\S]*?)<\/div>/;
const dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/; const dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/;
const subMatch = subRegex.exec(serverHtmlSource); const subContent = subRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const softsubMatch = softsubRegex.exec(serverHtmlSource); const softsubContent = softsubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const dubMatch = dubRegex.exec(serverHtmlSource); const dubContent = dubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const subContent = subMatch ? subMatch[1].trim() : "";
const softsubContent = softsubMatch ? softsubMatch[1].trim() : "";
const dubContent = dubMatch ? dubMatch[1].trim() : "";
const extractServerId = (content) => { const extractServerId = (content) => {
if (!content) { if (!content) return null;
return null;
}
const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content); const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content);
if (preferred?.[1]) { if (preferred?.[1]) return preferred[1];
return preferred[1]; return /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content)?.[1] || null;
}
const fallback = /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content);
return fallback?.[1] || null;
}; };
const serverIdDub = extractServerId(dubContent); const serverIdDub = extractServerId(dubContent);
@@ -180,93 +174,68 @@ async function extractStreamUrl(url) {
); );
const tokenResults = await Promise.all(tokenPromises); const tokenResults = await Promise.all(tokenPromises);
const streamUrls = tokenResults.map(result => { const serverIdMap = {
const serverIdMap = { "Dub": serverIdDub,
"Dub": serverIdDub, "Softsub": serverIdSoftsub,
"Softsub": serverIdSoftsub, "Sub": serverIdSub
"Sub": serverIdSub };
};
return {
type: result.name,
url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
};
});
const processStreams = async (streamUrls) => { const streamUrls = tokenResults.map(result => ({
const streamResponses = await Promise.all( type: result.name,
streamUrls.map(async ({ type, url }) => { url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
try { }));
const res = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const json = await res.json();
return {
type: type,
result: json.result
};
} catch (error) {
console.log(`Error fetching ${type} stream:`, error);
return {
type: type,
result: null
};
}
})
);
const decryptRequestData = streamResponses // Step 1: fetch links/view via proxy
.filter(item => item.result) const streamResponses = await Promise.all(
.map(item => ({ streamUrls.map(async ({ type, url }) => {
name: item.type,
data: item.result
}));
if (decryptRequestData.length === 0) {
return {};
}
const decryptPromises = decryptRequestData.map(item =>
fetchv2(`https://enc-dec.app/api/dec-kai?text=${encodeURIComponent(item.data)}`)
.then(res => res.json())
.then(json => ({ name: item.name, data: JSON.stringify(json.result) }))
.catch(err => ({ name: item.name, error: err.toString() }))
);
const decryptResults = await Promise.all(decryptPromises);
const finalResults = {};
decryptResults.forEach(result => {
try { try {
const parsed = JSON.parse(result.data); const res = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
finalResults[result.name] = parsed.url; const json = await res.json();
console.log(`decrypted${result.name} URL:` + parsed.url); return { type, result: json.result };
} catch (error) { } catch (error) {
console.log(`Error parsing ${result.name} result:`, error); console.log(`Error fetching ${type} stream:`, error);
finalResults[result.name] = null; return { type, result: null };
} }
}); })
);
return finalResults; // Step 2: decrypt with browser UA — no encodeURIComponent
}; const decryptPromises = streamResponses
.filter(item => item.result)
.map(item =>
fetchv2(`https://enc-dec.app/api/dec-kai?text=${item.result}`, headers)
.then(res => res.json())
.then(json => {
console.log(`decrypted ${item.type} URL:`, json.result?.url);
return { name: item.type, url: json.result?.url || null };
})
.catch(err => ({ name: item.type, url: null }))
);
const decryptResults = await Promise.all(decryptPromises);
const decryptedUrls = await processStreams(streamUrls); const urlMap = Object.fromEntries(decryptResults.map(i => [i.name, i.url]));
const decryptedDub = decryptedUrls.Dub || decryptedUrls.Sub || decryptedUrls.Softsub; const decryptedDub = urlMap.Dub || urlMap.Sub || urlMap.Softsub;
console.log(decryptedDub); console.log("Using URL:", decryptedDub);
const headers = {
"Referer": "https://anikai.to/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
};
if (decryptedDub) { if (decryptedDub) {
const response = await fetchv2(decryptedDub.replace("/e/", "/media/"), headers); const mediaResponse = await fetchv2(decryptedDub.replace("/e/", "/media/"), headers);
const responseJson = await response.json(); const responseJson = await mediaResponse.json();
const result = responseJson?.result; const result = responseJson?.result;
const postData = { const postData = {
"text": result, "text": result,
"agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" "agent": headers["User-Agent"]
} };
const finalResponse = await fetchv2("https://enc-dec.app/api/dec-mega", { "Content-Type": "application/json" }, "POST", JSON.stringify(postData)); const finalResponse = await fetchv2(
"https://enc-dec.app/api/dec-mega",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify(postData)
);
const finalJson = await finalResponse.json(); const finalJson = await finalResponse.json();
console.log("dec-mega result:", finalJson);
const m3u8Link = finalJson?.result?.sources?.[0]?.file; const m3u8Link = finalJson?.result?.sources?.[0]?.file;
return m3u8Link; return m3u8Link;
@@ -274,7 +243,7 @@ async function extractStreamUrl(url) {
return "error"; return "error";
} catch (error) { } catch (error) {
console.log("Fetch error:"+ error); console.log("Fetch error:" + error);
return "https://error.org"; return "https://error.org";
} }
} }
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "50/50", "name": "50/50",
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s" "icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
}, },
"version": "1.1.4", "version": "1.1.5",
"language": "English", "language": "English",
"streamType": "HLS", "streamType": "HLS",
"quality": "1080p", "quality": "1080p",
+59 -94
View File
@@ -114,6 +114,11 @@ async function extractEpisodes(url) {
} }
async function extractStreamUrl(url) { async function extractStreamUrl(url) {
const headers = {
"Referer": "https://anikai.to/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
};
try { try {
const tokenMatch = url.match(/token=([^&]+)/); const tokenMatch = url.match(/token=([^&]+)/);
if (tokenMatch && tokenMatch[1]) { if (tokenMatch && tokenMatch[1]) {
@@ -124,8 +129,7 @@ async function extractStreamUrl(url) {
url = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`); url = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
} }
const fetchUrl = `${url}`; const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(fetchUrl));
const text = await response.text(); const text = await response.text();
let ajaxResultHtml = ""; let ajaxResultHtml = "";
@@ -141,25 +145,15 @@ async function extractStreamUrl(url) {
const subRegex = /<div class="server-items lang-group" data-id="sub"[^>]*>([\s\S]*?)<\/div>/; const subRegex = /<div class="server-items lang-group" data-id="sub"[^>]*>([\s\S]*?)<\/div>/;
const softsubRegex = /<div class="server-items lang-group" data-id="softsub"[^>]*>([\s\S]*?)<\/div>/; const softsubRegex = /<div class="server-items lang-group" data-id="softsub"[^>]*>([\s\S]*?)<\/div>/;
const dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/; const dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/;
const subMatch = subRegex.exec(serverHtmlSource); const subContent = subRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const softsubMatch = softsubRegex.exec(serverHtmlSource); const softsubContent = softsubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const dubMatch = dubRegex.exec(serverHtmlSource); const dubContent = dubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const subContent = subMatch ? subMatch[1].trim() : "";
const softsubContent = softsubMatch ? softsubMatch[1].trim() : "";
const dubContent = dubMatch ? dubMatch[1].trim() : "";
const extractServerId = (content) => { const extractServerId = (content) => {
if (!content) { if (!content) return null;
return null;
}
const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content); const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content);
if (preferred?.[1]) { if (preferred?.[1]) return preferred[1];
return preferred[1]; return /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content)?.[1] || null;
}
const fallback = /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content);
return fallback?.[1] || null;
}; };
const serverIdDub = extractServerId(dubContent); const serverIdDub = extractServerId(dubContent);
@@ -180,97 +174,68 @@ async function extractStreamUrl(url) {
); );
const tokenResults = await Promise.all(tokenPromises); const tokenResults = await Promise.all(tokenPromises);
const streamUrls = tokenResults.map(result => { const serverIdMap = {
const serverIdMap = { "Dub": serverIdDub,
"Dub": serverIdDub, "Softsub": serverIdSoftsub,
"Softsub": serverIdSoftsub, "Sub": serverIdSub
"Sub": serverIdSub };
};
return {
type: result.name,
url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
};
});
const processStreams = async (streamUrls) => { const streamUrls = tokenResults.map(result => ({
const streamResponses = await Promise.all( type: result.name,
streamUrls.map(async ({ type, url }) => { url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
try { }));
const res = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const json = await res.json();
return {
type: type,
result: json.result
};
} catch (error) {
console.log(`Error fetching ${type} stream:`, error);
return {
type: type,
result: null
};
}
})
);
const decryptRequestData = streamResponses // Step 1: fetch links/view via proxy
.filter(item => item.result) const streamResponses = await Promise.all(
.map(item => ({ streamUrls.map(async ({ type, url }) => {
name: item.type,
data: item.result
}));
if (decryptRequestData.length === 0) {
return {};
}
const decryptPromises = decryptRequestData.map(item =>
fetchv2(`https://enc-dec.app/api/dec-kai?text=${encodeURIComponent(item.data)}`)
.then(res => res.json())
.then(json => ({ name: item.name, data: JSON.stringify(json.result) }))
.catch(err => ({ name: item.name, error: err.toString() }))
);
const decryptResults = await Promise.all(decryptPromises);
const finalResults = {};
decryptResults.forEach(result => {
try { try {
const parsed = JSON.parse(result.data); const res = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
finalResults[result.name] = parsed.url; const json = await res.json();
console.log(`decrypted${result.name} URL:` + parsed.url); return { type, result: json.result };
} catch (error) { } catch (error) {
console.log(`Error parsing ${result.name} result:`, error); console.log(`Error fetching ${type} stream:`, error);
finalResults[result.name] = null; return { type, result: null };
} }
}); })
);
return finalResults; // Step 2: decrypt with browser UA — no encodeURIComponent
}; const decryptPromises = streamResponses
.filter(item => item.result)
.map(item =>
fetchv2(`https://enc-dec.app/api/dec-kai?text=${item.result}`, headers)
.then(res => res.json())
.then(json => {
console.log(`decrypted ${item.type} URL:`, json.result?.url);
return { name: item.type, url: json.result?.url || null };
})
.catch(err => ({ name: item.type, url: null }))
);
const decryptResults = await Promise.all(decryptPromises);
const decryptedUrls = await processStreams(streamUrls); const urlMap = Object.fromEntries(decryptResults.map(i => [i.name, i.url]));
const decryptedSub = decryptedUrls.Sub || decryptedUrls.Dub || decryptedUrls.Softsub; const decryptedSub = urlMap.Sub || urlMap.Dub || urlMap.Softsub;
console.log(decryptedSub); console.log("Using URL:", decryptedSub);
const headers = {
"Referer": "https://anikai.to/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
};
if (decryptedSub) { if (decryptedSub) {
const response = await fetchv2(decryptedSub.replace("/e/", "/media/"), headers); const mediaResponse = await fetchv2(decryptedSub.replace("/e/", "/media/"), headers);
const responseJson = await response.json(); const responseJson = await mediaResponse.json();
const result = responseJson?.result; const result = responseJson?.result;
const postData = { const postData = {
"text": result, "text": result,
"agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" "agent": headers["User-Agent"]
} };
console.log(postData); const finalResponse = await fetchv2(
"https://enc-dec.app/api/dec-mega",
const finalResponse = await fetchv2("https://enc-dec.app/api/dec-mega", { "Content-Type": "application/json" }, "POST", JSON.stringify(postData)); { "Content-Type": "application/json" },
"POST",
JSON.stringify(postData)
);
const finalJson = await finalResponse.json(); const finalJson = await finalResponse.json();
console.log(finalJson); console.log("dec-mega result:", finalJson);
const m3u8Link = finalJson?.result?.sources?.[0]?.file; const m3u8Link = finalJson?.result?.sources?.[0]?.file;
return m3u8Link; return m3u8Link;
@@ -278,7 +243,7 @@ async function extractStreamUrl(url) {
return "error"; return "error";
} catch (error) { } catch (error) {
console.log("Fetch error:"+ error); console.log("Fetch error:" + error);
return "https://error.org"; return "https://error.org";
} }
} }
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "50/50", "name": "50/50",
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s" "icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
}, },
"version": "1.1.2", "version": "1.1.3",
"language": "English", "language": "English",
"streamType": "HLS", "streamType": "HLS",
"quality": "1080p", "quality": "1080p",