source/franime/franime.js
2025-10-11 17:18:45 +02:00

139 lines
4 KiB
JavaScript

async function searchResults(keyword) {
try {
const response = await fetchv2("https://api.franime.fr/api/animes");
const data = await response.json();
const results = data
.filter(anime => anime.title.toLowerCase().includes(keyword.toLowerCase()))
.map(anime => ({
href: anime.id.toString(),
title: anime.title,
image: anime.affiche
}));
return JSON.stringify(results);
} catch (err) {
return JSON.stringify([{
title: "Error",
image: "Error",
href: "Error"
}]);
}
}
async function extractDetails(id) {
try {
const response = await fetchv2("https://api.franime.fr/api/animes");
const data = await response.json();
const anime = data.find(item => item.id === Number(id));
if (!anime) {
return JSON.stringify([{
description: "Not found",
aliases: "N/A",
airdate: "N/A"
}]);
}
return JSON.stringify([{
description: anime.description || "N/A",
aliases: anime.titles ? Object.values(anime.titles).join(", ") : "N/A",
airdate: anime.startDate || "N/A"
}]);
} catch (err) {
return JSON.stringify([{
description: "Error",
aliases: "Error",
airdate: "Error"
}]);
}
}
async function extractEpisodes(id) {
const results = [];
try {
const response = await fetchv2("https://api.franime.fr/api/animes");
const data = await response.json();
const anime = data.find(item => item.id === Number(id));
if (!anime || !anime.saisons) {
return JSON.stringify([{
href: "N/A",
number: "N/A"
}]);
}
anime.saisons.forEach((season, seasonIndex) => {
season.episodes.forEach((episode, episodeIndex) => {
results.push({
href: `${id}/${seasonIndex}/${episodeIndex}`,
number: episodeIndex + 1
});
});
});
return JSON.stringify(results);
} catch (err) {
return JSON.stringify([{
href: "Error",
number: "Error"
}]);
}
}
async function extractStreamUrl(id) {
try {
const headers = {
"Host": "api.franime.fr",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:143.0) Gecko/20100101 Firefox/143.0",
"Referer": "https://franime.fr/",
"Content-Type": "application/json",
"Origin": "https://franime.fr",
"Connection": "keep-alive",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"Priority": "u=0",
"TE": "trailers"
};
async function fetchUntilMp4(type) {
let i = 0;
while (i < 10) {
const url = `https://api.franime.fr/api/anime/${id}/${type}/${i}`;
const res = await fetchv2(url, headers);
const text = await res.text();
console.log(type.toUpperCase(), i, text);
if (text.includes("Aucun lecteur disponible")) return null;
if (text.endsWith(".mp4")) return text;
i++;
}
}
const vf = await fetchUntilMp4("vf");
const vo = await fetchUntilMp4("vo");
const streams = [];
if (vf) streams.push("VOSTFR", vf);
if (vo) streams.push("VF", vo);
const final = {
streams,
subtitles: ""
};
console.log("RETURN: " + JSON.stringify(final));
return JSON.stringify(final);
} catch (error) {
console.log("Error in extractStreamUrl:", error);
return JSON.stringify({
streams: [],
subtitles: ""
});
}
}