This commit is contained in:
aka paul
2026-05-10 12:58:17 +02:00
parent 7cced4311b
commit 92fa874883
9 changed files with 407 additions and 391 deletions
+40 -12
View File
@@ -27,7 +27,7 @@ async function searchResults(query) {
if (fullHref && imageSrc && cleanTitle) {
results.push({
href: fullHref,
image: imageSrc,
image: "https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(imageSrc),
title: cleanTitle
});
}
@@ -44,7 +44,7 @@ async function searchResults(query) {
`${searchBaseUrl}${encodedQuery}&page=3`
];
const responses = await Promise.all(urls.map(url => fetchv2(url)));
const responses = await Promise.all(urls.map(url => fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url))));
const htmlTexts = await Promise.all(responses.map(response => response.text()));
@@ -147,15 +147,17 @@ async function extractStreamUrl(url) {
const responseData = await response.json();
const cleanedHtml = cleanJsonHtml(responseData.result);
const server1Regex = /<div class="server wnav-item"[^>]*data-lid="([^"]+)"[^>]*>\s*<span>Server 1<\/span>/;
const server1Match = server1Regex.exec(cleanedHtml);
const spanRegex = /<div class="server wnav-item"[^>]*data-lid="([^"]+)"[^>]*>/g;
const ids = [];
let match;
while ((match = spanRegex.exec(cleanedHtml)) !== null) ids.push(match[1]);
if (!server1Match) {
console.log("Server 1 not found");
if (ids.length === 0) {
console.log("No servers found");
return "error";
}
const serverId = server1Match[1];
const serverId = ids.length > 1 ? ids[1] : ids[0];
const tokenData = await fetchv2(`https://enc-dec.app/api/enc-movies-flix?text=${encodeURIComponent(serverId)}`)
.then(res => res.json());
@@ -203,7 +205,25 @@ async function extractStreamUrl(url) {
? subtitles.find(sub => sub.label === "English")?.file.replace(/\\\//g, "/")
: "N/A";
const mediaResponse = await fetchv2(decryptedUrl.replace("/e/", "/media/"), headers);
let finalUrl = decryptedUrl;
if (finalUrl.includes(".to/iframe")) {
try {
const iframeResponse = await fetchv2(finalUrl, headers);
const iframeHtml = await iframeResponse.text();
const iframeSrcMatch = iframeHtml.match(/<iframe[^>]+src="([^"]+)"/i);
if (iframeSrcMatch && iframeSrcMatch[1]) {
finalUrl = iframeSrcMatch[1];
} else {
console.log("No iframe src found in:", finalUrl);
return "error";
}
} catch (e) {
console.log("Error fetching iframe:", e);
return "error";
}
}
const mediaResponse = await fetchv2(finalUrl.replace("/e/", "/media/"), headers);
const mediaJson = await mediaResponse.json();
const result = mediaJson?.result;
@@ -220,8 +240,16 @@ async function extractStreamUrl(url) {
).then(res => res.json());
console.log("Final JSON: " + JSON.stringify(finalJson));
const m3u8Link = finalJson?.result?.sources?.[0]?.file;
const m3u8Response = await fetchv2(m3u8Link);
const streams = [];
if (m3u8Link) {
streams.push({
title: "Auto",
streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + m3u8Link
});
}
/*
const m3u8Response = await fetchv2("https://1anime.app/api/m3u8-proxy?url=" + encodeURIComponent(m3u8Link));
const m3u8Text = await m3u8Response.text();
const baseUrl = m3u8Link.substring(0, m3u8Link.lastIndexOf('/') + 1);
@@ -244,12 +272,12 @@ async function extractStreamUrl(url) {
const streamPath = lines[i + 1].trim();
streams.push({
title: quality,
streamUrl: baseUrl + streamPath
streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + encodeURIComponent(baseUrl + streamPath)
});
}
}
}
*/
const returnValue = {
streams: streams,
subtitles: englishSubUrl !== "N/A" ? englishSubUrl : ""
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "50/50",
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
},
"version": "1.2.3",
"version": "1.2.4",
"language": "English",
"streamType": "HLS",
"quality": "1080p",
+97 -106
View File
@@ -117,20 +117,27 @@ async function extractEpisodes(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"
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0",
"Accept": "text/html, */*; q=0.01",
"Accept-Language": "en-US,en;q=0.5",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
};
let actualUrl = url;
try {
const tokenMatch = actualUrl.match(/token=([^&]+)/);
if (tokenMatch && tokenMatch[1]) {
const rawToken = tokenMatch[1];
const encryptResponse = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(rawToken)}`);
const encryptData = await encryptResponse.json();
const encryptedToken = encryptData.result;
actualUrl = actualUrl.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
}
const tokenMatch = url.match(/token=([^&]+)/);
if (!tokenMatch?.[1]) throw new Error("No token found in URL");
const rawToken = tokenMatch[1];
const encTokenRes = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(rawToken)}`);
const encTokenData = await encTokenRes.json();
const encryptedToken = encTokenData.result;
const actualUrl = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
const response = await fetchv2(actualUrl);
const text = await response.text();
@@ -144,115 +151,96 @@ async function extractStreamUrl(url) {
const cleanedAjaxResultHtml = cleanJsonHtml(ajaxResultHtml);
const serverHtmlSource = cleanedAjaxResultHtml || cleanedHtml;
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 dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/;
const subMatch = subRegex.exec(serverHtmlSource);
const softsubMatch = softsubRegex.exec(serverHtmlSource);
const dubMatch = dubRegex.exec(serverHtmlSource);
const subContent = subMatch ? subMatch[1].trim() : "";
const softsubContent = softsubMatch ? softsubMatch[1].trim() : "";
const dubContent = dubMatch ? dubMatch[1].trim() : "";
const extractServerId = (content) => {
if (!content) return null;
const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content);
if (preferred?.[1]) return preferred[1];
return /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content)?.[1] || null;
const extractServerIds = (type) => {
const regex = new RegExp(`<div class="server-items lang-group" data-id="${type}"[^>]*>([\\s\\S]*?)<\\/div>`);
const content = regex.exec(serverHtmlSource)?.[1] ?? "";
const spanRegex = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>/g;
const ids = [];
let match;
while ((match = spanRegex.exec(content)) !== null) ids.push(match[1]);
console.log(`[extractStreamUrl] ${type} ids:`, ids);
return ids.length > 1 ? ids[1] : ids[0] ?? null;
};
const serverIdDub = extractServerId(dubContent);
const serverIdSoftsub = extractServerId(softsubContent);
const serverIdSub = extractServerId(subContent);
const dubType = url.includes("dub") ? "dub" : "sub";
const types = dubType === "sub" ? ["sub", "softsub"] : ["dub"];
const tokenRequestData = [
{ name: "Dub", data: serverIdDub },
{ name: "Softsub", data: serverIdSoftsub },
{ name: "Sub", data: serverIdSub }
].filter(item => item.data);
const servers = types
.map(type => ({ type, lid: extractServerIds(type) }))
.filter(s => s.lid);
const tokenPromises = tokenRequestData.map(item =>
fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(item.data)}`)
.then(res => res.json())
.then(json => ({ name: item.name, data: json.result }))
.catch(err => ({ name: item.name, error: err.toString() }))
);
const tokenResults = await Promise.all(tokenPromises);
const streams = [];
const subtitles = [];
const serverIdMap = {
"Dub": serverIdDub,
"Softsub": serverIdSoftsub,
"Sub": serverIdSub
};
const streamUrls = tokenResults.map(result => ({
type: result.name,
url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
}));
const streamResponses = await Promise.all(
streamUrls.map(async ({ type, url }) => {
try {
const res = await fetchv2(url);
const json = await res.json();
return { type, result: json.result };
} catch {
return { type, result: null };
}
})
);
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 => ({ name: item.type, url: json.result?.url || null }))
.catch(() => ({ name: item.type, url: null }))
);
const decryptResults = await Promise.all(decryptPromises);
const urlMap = Object.fromEntries(decryptResults.map(i => [i.name, i.url]));
const decryptedSub = urlMap.Sub;
const decryptedDub = urlMap.Dub;
const decryptedRaw = urlMap.Softsub;
async function getStream(url) {
await Promise.all(servers.map(async ({ type, lid }) => {
try {
const response = await fetchv2(url.replace("/e/", "/media/"), headers);
const responseJson = await response.json();
const result = responseJson?.result;
const decLidRes = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(lid)}`);
const decLidData = await decLidRes.json();
const decodedLid = decLidData.result;
const finalResponse = await fetchv2(
const viewRes = await fetchv2(`https://anikai.to/ajax/links/view?id=${lid}&_=${decodedLid}`);
const viewJson = await viewRes.json();
const encodedResult = viewJson.result;
const decRes = await fetchv2(
"https://enc-dec.app/api/dec-kai",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify({ text: encodedResult })
);
const decJson = await decRes.json();
let iframeUrl = decJson.result?.url ?? null;
if (!iframeUrl) return;
if (iframeUrl.includes("anikai.to/iframe")) {
const iframePageRes = await fetchv2(iframeUrl, headers);
const iframePageText = await iframePageRes.text();
const iframeSrcMatch = iframePageText.match(/<iframe[^>]+src="([^"]+)"/i);
if (iframeSrcMatch && iframeSrcMatch[1]) {
iframeUrl = iframeSrcMatch[1];
console.log(`[extractStreamUrl] fallback iframeUrl for ${type}:`, iframeUrl);
}
}
const mediaUrl = iframeUrl.replace("/e/", "/media/").replace("/e2/", "/media/");
const mediaRes = await fetchv2(mediaUrl, headers);
const mediaJson = await mediaRes.json();
const encodedM3u8 = mediaJson?.result;
if (!encodedM3u8) return;
const finalRes = await fetchv2(
"https://enc-dec.app/api/dec-mega",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify({ text: result, agent: headers["User-Agent"] })
JSON.stringify({ text: encodedM3u8, agent: headers["User-Agent"] })
);
const finalJson = await finalRes.json();
const finalJson = await finalResponse.json();
return finalJson?.result?.sources?.[0]?.file || null;
} catch {
return null;
const sources = finalJson?.result?.sources ?? [];
const tracks = finalJson?.result?.tracks ?? [];
const file = sources[0]?.file ?? null;
if (file) {
const titleMap = { sub: "Hardsub English", softsub: "Original audio", dub: "Dubbed English" };
streams.push({ title: titleMap[type] || type, streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + file });
}
for (const track of tracks) {
if (track.file && track.label) {
subtitles.push({ url: track.file, language: track.label });
}
}
} catch (e) {
console.log(`[extractStreamUrl] error for ${type}:`, e.toString());
}
}
}));
const [subStream, dubStream, rawStream] = await Promise.all([
decryptedSub ? getStream(decryptedSub) : Promise.resolve(null),
decryptedDub ? getStream(decryptedDub) : Promise.resolve(null),
decryptedRaw ? getStream(decryptedRaw) : Promise.resolve(null)
]);
console.log("[extractStreamUrl] Sub:", subStream, "Dub:", dubStream, "Softsub:", rawStream);
const streams = [];
if (subStream) streams.push({ title: "Hardsub English", streamUrl: subStream });
if (dubStream) streams.push({ title: "Dubbed English", streamUrl: dubStream });
if (rawStream) streams.push({ title: "Original audio", streamUrl: rawStream });
return JSON.stringify({ streams, subtitles: "" });
return JSON.stringify({ streams, subtitles });
} catch (error) {
console.error("Animekai fetch error:" + error);
@@ -260,6 +248,9 @@ async function extractStreamUrl(url) {
}
}
function cleanHtmlSymbols(string) {
if (!string) {
return "";
+116 -120
View File
@@ -114,138 +114,134 @@ async function extractEpisodes(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"
};
const headers = {
"Referer": "https://anikai.to/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0",
"Accept": "text/html, */*; q=0.01",
"Accept-Language": "en-US,en;q=0.5",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
};
try {
const tokenMatch = url.match(/token=([^&]+)/);
if (tokenMatch && tokenMatch[1]) {
const rawToken = tokenMatch[1];
const encryptResponse = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(rawToken)}`);
const encryptData = await encryptResponse.json();
const encryptedToken = encryptData.result;
url = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
}
const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const text = await response.text();
let ajaxResultHtml = "";
try {
const parsedAjax = JSON.parse(text);
ajaxResultHtml = parsedAjax?.result || "";
} catch {}
const tokenMatch = url.match(/token=([^&]+)/);
if (!tokenMatch?.[1]) throw new Error("No token found in URL");
const rawToken = tokenMatch[1];
const cleanedHtml = cleanJsonHtml(text);
const cleanedAjaxResultHtml = cleanJsonHtml(ajaxResultHtml);
const serverHtmlSource = cleanedAjaxResultHtml || cleanedHtml;
const encTokenRes = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(rawToken)}`);
const encTokenData = await encTokenRes.json();
const encryptedToken = encTokenData.result;
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 dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/;
const subContent = subRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const softsubContent = softsubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const dubContent = dubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const actualUrl = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
const extractServerId = (content) => {
if (!content) return null;
const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content);
if (preferred?.[1]) return preferred[1];
return /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content)?.[1] || null;
};
const response = await fetchv2(actualUrl);
const text = await response.text();
const serverIdDub = extractServerId(dubContent);
const serverIdSoftsub = extractServerId(softsubContent);
const serverIdSub = extractServerId(subContent);
let ajaxResultHtml = "";
try {
const parsedAjax = JSON.parse(text);
ajaxResultHtml = parsedAjax?.result || "";
} catch {}
const tokenRequestData = [
{ name: "Dub", data: serverIdDub },
{ name: "Softsub", data: serverIdSoftsub },
{ name: "Sub", data: serverIdSub }
].filter(item => item.data);
const cleanedHtml = cleanJsonHtml(text);
const cleanedAjaxResultHtml = cleanJsonHtml(ajaxResultHtml);
const serverHtmlSource = cleanedAjaxResultHtml || cleanedHtml;
const tokenPromises = tokenRequestData.map(item =>
fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(item.data)}`)
.then(res => res.json())
.then(json => ({ name: item.name, data: json.result }))
.catch(err => ({ name: item.name, error: err.toString() }))
);
const tokenResults = await Promise.all(tokenPromises);
const serverIdMap = {
"Dub": serverIdDub,
"Softsub": serverIdSoftsub,
"Sub": serverIdSub
};
const streamUrls = tokenResults.map(result => ({
type: result.name,
url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
}));
// Step 1: fetch links/view via proxy
const streamResponses = await Promise.all(
streamUrls.map(async ({ type, url }) => {
try {
const res = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const json = await res.json();
return { type, result: json.result };
} catch (error) {
console.log(`Error fetching ${type} stream:`, error);
return { type, result: null };
}
})
);
// 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 urlMap = Object.fromEntries(decryptResults.map(i => [i.name, i.url]));
const decryptedDub = urlMap.Dub || urlMap.Sub || urlMap.Softsub;
console.log("Using URL:", decryptedDub);
if (decryptedDub) {
const mediaResponse = await fetchv2(decryptedDub.replace("/e/", "/media/"), headers);
const responseJson = await mediaResponse.json();
const result = responseJson?.result;
const postData = {
"text": result,
"agent": headers["User-Agent"]
const extractServerIds = (type) => {
const regex = new RegExp(`<div class="server-items lang-group" data-id="${type}"[^>]*>([\\s\\S]*?)<\\/div>`);
const content = regex.exec(serverHtmlSource)?.[1] ?? "";
const spanRegex = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>/g;
const ids = [];
let match;
while ((match = spanRegex.exec(content)) !== null) ids.push(match[1]);
return ids.length > 1 ? ids[1] : ids[0] ?? null;
};
const finalResponse = await fetchv2(
"https://enc-dec.app/api/dec-mega",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify(postData)
);
const finalJson = await finalResponse.json();
console.log("dec-mega result:", finalJson);
const m3u8Link = finalJson?.result?.sources?.[0]?.file;
const types = ["dub"];
return m3u8Link;
const servers = types
.map(type => ({ type, lid: extractServerIds(type) }))
.filter(s => s.lid);
const streams = [];
const subtitles = [];
await Promise.all(servers.map(async ({ type, lid }) => {
try {
const decLidRes = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(lid)}`);
const decLidData = await decLidRes.json();
const decodedLid = decLidData.result;
const viewUrl = `https://anikai.to/ajax/links/view?id=${lid}&_=${decodedLid}`;
const viewRes = await fetchv2(viewUrl);
const viewJson = await viewRes.json();
const encodedResult = viewJson.result;
const decRes = await fetchv2(
"https://enc-dec.app/api/dec-kai",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify({ text: encodedResult })
);
const decJson = await decRes.json();
let iframeUrl = decJson.result?.url ?? null;
if (!iframeUrl) return;
if (iframeUrl.includes("anikai.to/iframe")) {
const iframePageRes = await fetchv2(iframeUrl, headers);
const iframePageText = await iframePageRes.text();
const iframeSrcMatch = iframePageText.match(/<iframe[^>]+src="([^"]+)"/i);
if (iframeSrcMatch && iframeSrcMatch[1]) {
iframeUrl = iframeSrcMatch[1];
}
}
const mediaUrl = iframeUrl.replace("/e/", "/media/").replace("/e2/", "/media/");
const mediaRes = await fetchv2(mediaUrl, headers);
const mediaJson = await mediaRes.json();
const encodedM3u8 = mediaJson?.result;
if (!encodedM3u8) return;
const finalRes = await fetchv2(
"https://enc-dec.app/api/dec-mega",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify({ text: encodedM3u8, agent: headers["User-Agent"] })
);
const finalJson = await finalRes.json();
const sources = finalJson?.result?.sources ?? [];
const tracks = finalJson?.result?.tracks ?? [];
const file = sources[0]?.file ?? null;
if (file) {
const titleMap = { dub: "Dubbed English" };
streams.push({ title: titleMap[type] || type, streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + file });
}
for (const track of tracks) {
if (track.file && track.label) {
subtitles.push({ url: track.file, language: track.label });
}
}
} catch (e) {
console.log(`[extractStreamUrl] error for ${type}:`, e.toString());
}
}));
return streams.length > 0 ? streams[0].streamUrl : "error";
} catch (error) {
console.error("Animekai fetch error:" + error);
return "https://error.org";
}
return "error";
} catch (error) {
console.log("Fetch error:" + error);
return "https://error.org";
}
}
function cleanHtmlSymbols(string) {
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "50/50",
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
},
"version": "1.1.5",
"version": "1.1.6",
"language": "English",
"streamType": "HLS",
"quality": "1080p",
+104 -115
View File
@@ -121,131 +121,120 @@ async function extractStreamUrl(url) {
try {
const tokenMatch = url.match(/token=([^&]+)/);
if (tokenMatch && tokenMatch[1]) {
const rawToken = tokenMatch[1];
const encryptResponse = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(rawToken)}`);
const encryptData = await encryptResponse.json();
const encryptedToken = encryptData.result;
url = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
}
const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const text = await response.text();
if (!tokenMatch?.[1]) throw new Error("No token found in URL");
const rawToken = tokenMatch[1];
let ajaxResultHtml = "";
try {
const parsedAjax = JSON.parse(text);
ajaxResultHtml = parsedAjax?.result || "";
} catch {}
const encTokenRes = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(rawToken)}`);
const encTokenData = await encTokenRes.json();
const encryptedToken = encTokenData.result;
const cleanedHtml = cleanJsonHtml(text);
const cleanedAjaxResultHtml = cleanJsonHtml(ajaxResultHtml);
const serverHtmlSource = cleanedAjaxResultHtml || cleanedHtml;
const actualUrl = url.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
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 dubRegex = /<div class="server-items lang-group" data-id="dub"[^>]*>([\s\S]*?)<\/div>/;
const subContent = subRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const softsubContent = softsubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const dubContent = dubRegex.exec(serverHtmlSource)?.[1]?.trim() || "";
const response = await fetchv2(actualUrl);
const text = await response.text();
const extractServerId = (content) => {
if (!content) return null;
const preferred = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>\s*Server\s*1\s*<\/span>/i.exec(content);
if (preferred?.[1]) return preferred[1];
return /<span class="server"[^>]*data-lid="([^"]+)"/i.exec(content)?.[1] || null;
};
let ajaxResultHtml = "";
try {
const parsedAjax = JSON.parse(text);
ajaxResultHtml = parsedAjax?.result || "";
} catch {}
const serverIdDub = extractServerId(dubContent);
const serverIdSoftsub = extractServerId(softsubContent);
const serverIdSub = extractServerId(subContent);
const cleanedHtml = cleanJsonHtml(text);
const cleanedAjaxResultHtml = cleanJsonHtml(ajaxResultHtml);
const serverHtmlSource = cleanedAjaxResultHtml || cleanedHtml;
const tokenRequestData = [
{ name: "Dub", data: serverIdDub },
{ name: "Softsub", data: serverIdSoftsub },
{ name: "Sub", data: serverIdSub }
].filter(item => item.data);
const tokenPromises = tokenRequestData.map(item =>
fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(item.data)}`)
.then(res => res.json())
.then(json => ({ name: item.name, data: json.result }))
.catch(err => ({ name: item.name, error: err.toString() }))
);
const tokenResults = await Promise.all(tokenPromises);
const serverIdMap = {
"Dub": serverIdDub,
"Softsub": serverIdSoftsub,
"Sub": serverIdSub
};
const streamUrls = tokenResults.map(result => ({
type: result.name,
url: `https://anikai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}`
}));
// Step 1: fetch links/view via proxy
const streamResponses = await Promise.all(
streamUrls.map(async ({ type, url }) => {
try {
const res = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(url));
const json = await res.json();
return { type, result: json.result };
} catch (error) {
console.log(`Error fetching ${type} stream:`, error);
return { type, result: null };
}
})
);
// 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 urlMap = Object.fromEntries(decryptResults.map(i => [i.name, i.url]));
const decryptedSub = urlMap.Sub || urlMap.Dub || urlMap.Softsub;
console.log("Using URL:", decryptedSub);
if (decryptedSub) {
const mediaResponse = await fetchv2(decryptedSub.replace("/e/", "/media/"), headers);
const responseJson = await mediaResponse.json();
const result = responseJson?.result;
const postData = {
"text": result,
"agent": headers["User-Agent"]
const extractServerIds = (type) => {
const regex = new RegExp(`<div class="server-items lang-group" data-id="${type}"[^>]*>([\\s\\S]*?)<\\/div>`);
const content = regex.exec(serverHtmlSource)?.[1] ?? "";
const spanRegex = /<span class="server"[^>]*data-lid="([^"]+)"[^>]*>/g;
const ids = [];
let match;
while ((match = spanRegex.exec(content)) !== null) ids.push(match[1]);
return ids.length > 1 ? ids[1] : ids[0] ?? null;
};
const finalResponse = await fetchv2(
"https://enc-dec.app/api/dec-mega",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify(postData)
);
const finalJson = await finalResponse.json();
console.log("dec-mega result:", finalJson);
const m3u8Link = finalJson?.result?.sources?.[0]?.file;
const types = ["sub"];
return m3u8Link;
const servers = types
.map(type => ({ type, lid: extractServerIds(type) }))
.filter(s => s.lid);
const streams = [];
const subtitles = [];
await Promise.all(servers.map(async ({ type, lid }) => {
try {
const decLidRes = await fetchv2(`https://enc-dec.app/api/enc-kai?text=${encodeURIComponent(lid)}`);
const decLidData = await decLidRes.json();
const decodedLid = decLidData.result;
const viewUrl = `https://anikai.to/ajax/links/view?id=${lid}&_=${decodedLid}`;
const viewRes = await fetchv2(viewUrl);
const viewJson = await viewRes.json();
const encodedResult = viewJson.result;
const decRes = await fetchv2(
"https://enc-dec.app/api/dec-kai",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify({ text: encodedResult })
);
const decJson = await decRes.json();
let iframeUrl = decJson.result?.url ?? null;
if (!iframeUrl) return;
if (iframeUrl.includes("anikai.to/iframe")) {
const iframePageRes = await fetchv2(iframeUrl, headers);
const iframePageText = await iframePageRes.text();
const iframeSrcMatch = iframePageText.match(/<iframe[^>]+src="([^"]+)"/i);
if (iframeSrcMatch && iframeSrcMatch[1]) {
iframeUrl = iframeSrcMatch[1];
}
}
const mediaUrl = iframeUrl.replace("/e/", "/media/").replace("/e2/", "/media/");
const mediaRes = await fetchv2(mediaUrl, headers);
const mediaJson = await mediaRes.json();
const encodedM3u8 = mediaJson?.result;
if (!encodedM3u8) return;
const finalRes = await fetchv2(
"https://enc-dec.app/api/dec-mega",
{ "Content-Type": "application/json" },
"POST",
JSON.stringify({ text: encodedM3u8, agent: headers["User-Agent"] })
);
const finalJson = await finalRes.json();
const sources = finalJson?.result?.sources ?? [];
const tracks = finalJson?.result?.tracks ?? [];
const file = sources[0]?.file ?? null;
if (file) {
const titleMap = { sub: "Hardsub English" };
streams.push({ title: titleMap[type] || type, streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + file });
}
for (const track of tracks) {
if (track.file && track.label) {
subtitles.push({ url: track.file, language: track.label });
}
}
} catch (e) {
console.log(`[extractStreamUrl] error for ${type}:`, e.toString());
}
}));
return streams.length > 0 ? streams[0].streamUrl : "error";
} catch (error) {
console.error("Animekai fetch error:" + error);
return "https://error.org";
}
return "error";
} catch (error) {
console.log("Fetch error:" + error);
return "https://error.org";
}
}
function cleanHtmlSymbols(string) {
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "50/50",
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
},
"version": "1.1.3",
"version": "1.1.4",
"language": "English",
"streamType": "HLS",
"quality": "1080p",
+46 -34
View File
@@ -650,7 +650,16 @@ async function extractStreamUrl(url) {
async function getStream(url) {
try {
const response = await fetchv2(url.replace("/e/", "/media/"), headers);
if (url.includes("anikai.to/iframe")) {
const iframePageRes = await fetchv2(url, headers);
const iframePageText = await iframePageRes.text();
const iframeSrcMatch = iframePageText.match(/<iframe[^>]+src="([^"]+)"/i);
if (iframeSrcMatch && iframeSrcMatch[1]) {
url = iframeSrcMatch[1];
}
}
const response = await fetchv2(url.replace("/e/", "/media/").replace("/e2/", "/media/"), headers);
const responseJson = await response.json();
const result = responseJson?.result;
const finalResponse = await fetchv2(
@@ -673,9 +682,9 @@ async function extractStreamUrl(url) {
]);
const streams = [];
if (subStream) streams.push({ title: "Hardsub English", streamUrl: subStream });
if (dubStream) streams.push({ title: "Dubbed English", streamUrl: dubStream });
if (rawStream) streams.push({ title: "Original audio", streamUrl: rawStream });
if (subStream) streams.push({ title: "Hardsub English", streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + subStream });
if (dubStream) streams.push({ title: "Dubbed English", streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + dubStream });
if (rawStream) streams.push({ title: "Original audio", streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + rawStream });
const final = { streams, subtitles: "" };
console.log("RETURN: " + JSON.stringify(final));
@@ -702,19 +711,21 @@ async function extractStreamUrl(url) {
actualUrl = actualUrl.replace('&_=ENCRYPT_ME', `&_=${encryptedToken}`);
}
const response = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(actualUrl));
const response = await fetchv2(actualUrl);
const responseData = await response.json();
const cleanedHtml = cleanJsonHtml(responseData.result);
const server1Regex = /<div class="server wnav-item"[^>]*data-lid="([^"]+)"[^>]*>\s*<span>Server 1<\/span>/;
const server1Match = server1Regex.exec(cleanedHtml);
const spanRegex = /<div class="server wnav-item"[^>]*data-lid="([^"]+)"[^>]*>/g;
const ids = [];
let match;
while ((match = spanRegex.exec(cleanedHtml)) !== null) ids.push(match[1]);
if (!server1Match) {
console.log("Server 1 not found");
if (ids.length === 0) {
console.log("No servers found");
return "error";
}
const serverId = server1Match[1];
const serverId = ids.length > 1 ? ids[1] : ids[0];
const tokenData = await fetchv2(`https://enc-dec.app/api/enc-movies-flix?text=${encodeURIComponent(serverId)}`)
.then(res => res.json());
const token = tokenData.result;
@@ -725,7 +736,7 @@ async function extractStreamUrl(url) {
}
const streamUrl = `https://1movies.bz/ajax/links/view?id=${serverId}&_=${token}`;
const streamResponse = await fetchv2("https://deno-proxies-sznvnpnxwhbv.deno.dev/?url=" + encodeURIComponent(streamUrl));
const streamResponse = await fetchv2(streamUrl);
const streamData = await streamResponse.json();
if (!streamData.result) {
@@ -762,7 +773,25 @@ async function extractStreamUrl(url) {
? subtitles.find(sub => sub.label === "English")?.file.replace(/\\\//g, "/")
: "N/A";
const mediaResponse = await fetchv2(decryptedUrl.replace("/e/", "/media/"), headers);
let finalUrl = decryptedUrl;
if (finalUrl.includes(".to/iframe")) {
try {
const iframeResponse = await fetchv2(finalUrl, headers);
const iframeHtml = await iframeResponse.text();
const iframeSrcMatch = iframeHtml.match(/<iframe[^>]+src="([^"]+)"/i);
if (iframeSrcMatch && iframeSrcMatch[1]) {
finalUrl = iframeSrcMatch[1];
} else {
console.log("No iframe src found in:", finalUrl);
return "error";
}
} catch (e) {
console.log("Error fetching iframe:", e);
return "error";
}
}
const mediaResponse = await fetchv2(finalUrl.replace("/e/", "/media/"), headers);
const mediaJson = await mediaResponse.json();
const result = mediaJson?.result;
@@ -775,29 +804,12 @@ async function extractStreamUrl(url) {
const finalJson = JSON.parse(await finalResponse.text());
const m3u8Link = finalJson?.result?.sources?.[0]?.file;
const m3u8Response = await fetchv2(m3u8Link);
const m3u8Text = await m3u8Response.text();
const baseUrl = m3u8Link.substring(0, m3u8Link.lastIndexOf('/') + 1);
const streams = [];
const lines = m3u8Text.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith('#EXT-X-STREAM-INF:')) {
const resolutionMatch = line.match(/RESOLUTION=(\d+x\d+)/);
let quality = 'Unknown';
if (resolutionMatch) {
const [width, height] = resolutionMatch[1].split('x');
quality = `${height}p`;
}
if (i + 1 < lines.length) {
streams.push({
title: quality,
streamUrl: baseUrl + lines[i + 1].trim()
});
}
}
if (m3u8Link) {
streams.push({
title: "Auto",
streamUrl: "https://1anime.app/api/m3u8-proxy?url=" + m3u8Link
});
}
const returnValue = {
+1 -1
View File
@@ -5,7 +5,7 @@
"name": "50/50",
"icon": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ3122kQwublLkZ6rf1fEpUP79BxZOFmH9BSA&s"
},
"version": "1.3.1",
"version": "1.3.2",
"language": "English",
"streamType": "HLS",
"quality": "1080p",