From 1fd6ce327690467d30477b612a00cc8a5ae3a23d Mon Sep 17 00:00:00 2001 From: aka paul <50n50@noreply.localhost> Date: Sat, 1 Nov 2025 16:35:27 +0000 Subject: [PATCH] Add torrentio/torrentio.js --- torrentio/torrentio.js | 211 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 torrentio/torrentio.js diff --git a/torrentio/torrentio.js b/torrentio/torrentio.js new file mode 100644 index 0000000..d40249f --- /dev/null +++ b/torrentio/torrentio.js @@ -0,0 +1,211 @@ + +// Settings start +const preferedQualityOption = "Auto"; // ["Auto", "2160p", "1080p", "720p", "480p"] +const debridService = "realdebrid"; // ["realdebrid", "alldebrid", "premiumize", "torbox", "debridlink"] +const debridApiKey = ""; +// Settings end + +async function searchResults(keyword) { + try { + const moviesresponse = await fetchv2( + "https://v3-cinemeta.strem.io/catalog/movie/top/search=" + encodeURIComponent(keyword) + ".json" + ); + const moviesdata = await moviesresponse.json(); + + const results = moviesdata.metas.map(item => ({ + title: item.name.trim(), + image: item.poster.trim(), + href: "Movie: " + (item.id.startsWith("tt") ? item.id : "") + })); + + const showsresponse = await fetchv2( + "https://v3-cinemeta.strem.io/catalog/series/top/search=" + encodeURIComponent(keyword) + ".json" + ); + const showsdata = await showsresponse.json(); + + const showResults = showsdata.metas.map(item => ({ + title: item.name.trim(), + image: item.poster.trim(), + href: "TV: " + (item.id.startsWith("tt") ? item.id : "") + })); + + results.push(...showResults); + + return JSON.stringify(results); + } catch (err) { + return JSON.stringify([{ + title: "Error", + image: "Error", + href: "Error" + }]); + } +} + +async function extractDetails(ID) { + try { + let decodedID = decodeURIComponent(ID); + let actualID = decodedID; + let type = "movie"; + + if (decodedID.startsWith("Movie: ")) { + actualID = decodedID.replace("Movie: ", ""); + type = "movie"; + } else if (decodedID.startsWith("TV: ")) { + actualID = decodedID.replace("TV: ", ""); + type = "series"; + } + + const url = "https://v3-cinemeta.strem.io/meta/" + type + "/" + actualID + ".json"; + const response = await fetchv2(url); + const data = await response.json(); + + return JSON.stringify([{ + description: data.meta.description || "N/A", + aliases: "N/A", + airdate: data.meta.released || "N/A" + }]); + } catch (err) { + return JSON.stringify([{ + description: "Error", + aliases: "Error", + airdate: "Error" + }]); + } +} + +async function extractEpisodes(ID) { + let decodedID = decodeURIComponent(ID); + let actualID = decodedID; + let type = "movie"; + + if (decodedID.startsWith("Movie: ")) { + actualID = decodedID.replace("Movie: ", ""); + type = "movie"; + } else if (decodedID.startsWith("TV: ")) { + actualID = decodedID.replace("TV: ", ""); + type = "series"; + } + + const results = []; + + try { + if (type === "series") { + const response = await fetchv2("https://v3-cinemeta.strem.io/meta/series/" + actualID + ".json"); + const data = await response.json(); + + const videos = data.meta.videos || []; + + let currentSeason = 0; + let episodeCounter = 0; + + for (const video of videos) { + if (video.season !== currentSeason) { + currentSeason = video.season; + episodeCounter = 0; + } + + episodeCounter++; + + results.push({ + href: "TV: " + (video.id || ""), + number: episodeCounter + }); + } + + return JSON.stringify(results); + } else if (type === "movie") { + return JSON.stringify([{ + href: "Movie: " + (actualID || ""), + number: 1 + }]); + } + } catch (err) { + return JSON.stringify([{ + href: "Error", + number: "Error" + }]); + } +} + +async function extractStreamUrl(ID) { + let decodedID = decodeURIComponent(ID); + let actualID = decodedID; + let type = "movie"; + + if (decodedID.startsWith("Movie: ")) { + actualID = decodedID.replace("Movie: ", ""); + type = "movie"; + } else if (decodedID.startsWith("TV: ")) { + actualID = decodedID.replace("TV: ", ""); + type = "series"; + } + + try { + const endpoint = type === "movie" + ? "https://torrentio.strem.fun/" + debridService + "=" + debridApiKey + "/stream/movie/" + actualID + ".json" + : "https://torrentio.strem.fun/" + debridService + "=" + debridApiKey + "/stream/series/" + actualID + ".json"; + + const response = await fetchv2(endpoint); + const data = await response.json(); + + if (!data.streams || !Array.isArray(data.streams)) { + return JSON.stringify({ + streams: [], + subtitle: "https://none.com" + }); + } + + const streamsByQuality = { + "2160p": [], + "1080p": [], + "720p": [], + "480p": [] + }; + + for (const stream of data.streams) { + const name = stream.name || ""; + let quality = null; + + if (name.includes("4k") || name.includes("2160p")) { + quality = "2160p"; + } else if (name.includes("1080p")) { + quality = "1080p"; + } else if (name.includes("720p")) { + quality = "720p"; + } else if (name.includes("480p")) { + quality = "480p"; + } + + if (quality && streamsByQuality[quality]) { + streamsByQuality[quality].push({ + title: (stream.name || "Unknown").replace(/\n/g, " "), + streamUrl: stream.url || "", + headers: {} + }); + } + } + + let results = []; + + if (preferedQualityOption === "Auto") { + results.push(...streamsByQuality["2160p"].slice(0, 5)); + results.push(...streamsByQuality["1080p"].slice(0, 5)); + results.push(...streamsByQuality["720p"].slice(0, 5)); + results.push(...streamsByQuality["480p"].slice(0, 5)); + } else { + if (streamsByQuality[preferedQualityOption]) { + results = streamsByQuality[preferedQualityOption].slice(0, 10); + } + } + + return JSON.stringify({ + streams: results, + subtitle: "https://none.com" + }); + } catch (err) { + return JSON.stringify({ + streams: [], + subtitle: "https://none.com" + }); + } +} \ No newline at end of file