source/animelib/animelib.js
2025-11-01 13:50:08 +00:00

231 lines
8.4 KiB
JavaScript

async function searchResults(keyword) {
const results = [];
try {
const response = await fetchv2("https://api.cdnlibs.org/api/anime?fields[]=rate_avg&fields[]=rate&fields[]=releaseDate&q=" + keyword);
const json = await response.json();
if (json && Array.isArray(json.data)) {
for (const item of json.data) {
const image = item.cover?.default || item.cover?.thumbnail || "";
results.push({
title: item.eng_name || item.name || "Unknown",
image: "https://passthrough-worker.simplepostrequest.workers.dev/?simple=" + image + "&referer=https://animelib.org/",
href: item.slug_url || item.slug || item.id
});
}
}
return JSON.stringify(results);
} catch (err) {
return JSON.stringify([{
title: "Error",
image: "Error",
href: "Error"
}]);
}
}
async function extractDetails(slug) {
try {
const response = await fetchv2(
"https://api.cdnlibs.org/api/anime/" + slug +
"?fields[]=background&fields[]=eng_name&fields[]=otherNames&fields[]=summary&fields[]=releaseDate&fields[]=type_id&fields[]=caution&fields[]=views&fields[]=close_view&fields[]=rate_avg&fields[]=rate&fields[]=genres&fields[]=tags&fields[]=teams&fields[]=user&fields[]=franchise&fields[]=authors&fields[]=publisher&fields[]=userRating&fields[]=moderated&fields[]=metadata&fields[]=metadata.count&fields[]=metadata.close_comments&fields[]=anime_status_id&fields[]=time&fields[]=episodes&fields[]=episodes_count&fields[]=episodesSchedule&fields[]=shiki_rate"
);
const json = await response.json();
const data = json.data || {};
const aliases = Array.isArray(data.otherNames) ? data.otherNames.join(", ") : "";
return JSON.stringify([{
description: data.summary || "No summary available",
airdate: data.releaseDate || "Unknown",
aliases: aliases
}]);
} catch (err) {
return JSON.stringify([{
description: "Error",
airdate: "Error",
aliases: ""
}]);
}
}
async function extractEpisodes(slug) {
const results = [];
try {
const response = await fetchv2("https://api.cdnlibs.org/api/episodes?anime_id=" + slug);
const json = await response.json();
if (json && Array.isArray(json.data)) {
for (const episode of json.data) {
results.push({
href: episode.id ? String(episode.id) : "",
number: parseFloat(episode.number) || 0
});
}
}
return JSON.stringify(results);
} catch (err) {
return JSON.stringify([{
href: "Error",
number: "Error"
}]);
}
}
async function extractStreamUrl(ID) {
try {
const response = await fetchv2("https://api.cdnlibs.org/api/episodes/" + ID);
const json = await response.json();
const data = json.data || {};
const players = data.players || [];
const parserPromises = players
.filter(player => player.src && player.team && player.team.name)
.map(async (player) => {
try {
const kodikUrl = "https:" + player.src;
const qualitiesJson = await kodikParser(kodikUrl);
const qualities = JSON.parse(qualitiesJson);
let highestQuality = null;
let highestQualityNum = 0;
for (const quality in qualities) {
if (qualities[quality].src) {
const qualityNum = parseInt(quality.replace('p', '')) || 0;
if (qualityNum > highestQualityNum) {
highestQualityNum = qualityNum;
highestQuality = qualities[quality].src;
}
}
}
if (highestQuality) {
return {
title: player.team.name,
streamUrl: highestQuality,
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Referer": "https://kodik.info/"
}
};
}
return null;
} catch (err) {
return null;
}
});
const results = await Promise.all(parserPromises);
const streams = results.filter(stream => stream !== null);
return JSON.stringify({
streams: streams,
subtitle: "https://none.com"
});
} catch (err) {
return JSON.stringify({
streams: [],
subtitle: "https://none.com"
});
}
}
async function kodikParser(url) {
try {
const headers = {
"Referer": "https://v3.animelib.org/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
};
const response = await fetchv2(url, headers);
const htmlText = await response.text();
const urlParamsMatch = htmlText.match(/var\s+urlParams\s*=\s*'([^']+)'/);
const videoInfoTypeMatch = htmlText.match(/videoInfo\.type\s*=\s*'([^']+)'/);
const videoInfoHashMatch = htmlText.match(/videoInfo\.hash\s*=\s*'([^']+)'/);
const videoInfoIdMatch = htmlText.match(/videoInfo\.id\s*=\s*'([^']+)'/);
const urlParams = urlParamsMatch ? JSON.parse(urlParamsMatch[1]) : {};
const videoInfo_type = videoInfoTypeMatch ? videoInfoTypeMatch[1] : '';
const videoInfo_hash = videoInfoHashMatch ? videoInfoHashMatch[1] : '';
const videoInfo_id = videoInfoIdMatch ? videoInfoIdMatch[1] : '';
const finalData =
`d=${urlParams.d}` +
`&d_sign=${urlParams.d_sign}` +
`&pd=${urlParams.pd}` +
`&pd_sign=${urlParams.pd_sign}` +
`&ref=${urlParams.ref}` +
`&ref_sign=${urlParams.ref_sign}` +
`&bad_user=false&cdn_is_working=false` +
`&type=${videoInfo_type}&hash=${videoInfo_hash}&id=${videoInfo_id}&info=%7B%7D`;
const headers2 = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "https://kodik.info",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
"X-Requested-With": "XMLHttpRequest"
};
const apiResponse = await fetchv2("https://kodik.info/ftor", headers2, "POST", finalData);
const apiJson = await apiResponse.json();
const qualities = {};
if (apiJson?.links) {
for (const quality in apiJson.links) {
const qualityData = apiJson.links[quality];
if (qualityData && qualityData[0] && qualityData[0].src) {
const encodedSrc = qualityData[0].src;
const decodedUrl = decode(encodedSrc);
qualities[quality] = {
src: decodedUrl,
type: qualityData[0].type || 'application/x-mpegURL'
};
}
}
}
return JSON.stringify(qualities, null, 2);
} catch (error) {
console.log(error);
return JSON.stringify({ error: "error.org" });
}
}
function decode(input) {
const _0x1a = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "=", String.fromCharCode, ">="];
(function() {})();
const _map = _0x1a[0];
let _o = '',
_b = 0,
_c = 0;
const _r = [];
for (let _i = 0; _i < input.length; _i++) {
const _ch = input[_i];
if (/[a-zA-Z]/.test(_ch)) {
const _cc = _ch.charCodeAt(0);
const _max = _ch <= 'Z' ? 90 : 122;
let _sh = _cc + 18;
_r.push(String.fromCharCode(_sh <= _max ? _sh : _sh - 26));
} else _r.push(_ch);
}
const _rot = _r.join('');
for (let _j = 0; _j < _rot.length; _j++) {
const _ch = _rot[_j];
if (_ch === _0x1a[1]) break;
const _v = _map.indexOf(_ch);
if (_v === -1) continue;
_b = (_b << 6) | _v;
_c += 6;
if (_c >= 8) {
_c -= 8;
_o += _0x1a[2]((_b >> _c) & 0xFF);
}
}
return _o;
}