// Settings start const preferedQualityOption = "Auto"; // ["Auto", "2160p", "1080p", "720p", "480p"] const debridService = "realdebrid"; // ["realdebrid", "alldebrid", "premiumize", "torbox", "debridlink"] const debridApiKey = ""; const allowAdultContent = true; // [true, false] // 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 || []; const shouldAdjust = videos.length > 0 && videos[0].season === 0; let currentSeason = 0; let episodeCounter = 0; for (const video of videos) { const adjustedSeason = shouldAdjust ? video.season + 1 : video.season; if (adjustedSeason !== currentSeason) { currentSeason = adjustedSeason; episodeCounter = 0; } episodeCounter++; let adjustedId = video.id || ""; if (adjustedId && shouldAdjust) { const idParts = adjustedId.split(':'); if (idParts.length === 3) { idParts[1] = String(adjustedSeason); adjustedId = idParts.join(':'); } } results.push({ href: "TV: " + adjustedId, 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 userConfig = { streaming_provider: { service: debridService, token: debridApiKey } }; if (allowAdultContent) { userConfig.nudity_filter = ["Disable"]; userConfig.certification_filter = ["Disable"]; } else { userConfig.nudity_filter = ["Severe", "Moderate"]; userConfig.certification_filter = ["Adults+"]; } const url = await encrypt({ customUserData: userConfig }); const match = url.match(/\/([^\/]+)\/manifest\.json$/); const encryptedConfig = match ? match[1] : null; if (!encryptedConfig) { return JSON.stringify({ streams: [], subtitle: "https://none.com" }); } const endpoint = type === "movie" ? "https://mediafusion.elfhosted.com/" + encryptedConfig + "/stream/movie/" + actualID + ".json" : "https://mediafusion.elfhosted.com/" + encryptedConfig + "/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("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" }); } } async function encrypt(config = {}) { const baseUrl = config.baseUrl || 'https://mediafusion.elfhosted.com'; try { let userData; if (config.customUserData) { userData = config.customUserData; } else { userData = {}; if (config.provider && config.token) { userData.streaming_provider = { service: config.provider, token: config.token }; if (config.username) { userData.streaming_provider.username = config.username; } } if (config.catalogs && config.catalogs.length > 0) { userData.selected_catalogs = config.catalogs; } if (config.enableCatalogs !== undefined) { userData.enable_catalogs = config.enableCatalogs; } else { userData.enable_catalogs = true; } if (config.maxSizeGB !== undefined && config.maxSizeGB > 0) { userData.max_size = config.maxSizeGB * 1024 * 1024 * 1024; } if (config.maxStreamsPerResolution !== undefined) { userData.max_streams_per_resolution = config.maxStreamsPerResolution; } else { userData.max_streams_per_resolution = 10; } if (config.sortingPriority) { userData.torrent_sorting_priority = config.sortingPriority; } else { userData.torrent_sorting_priority = ["cached", "resolution", "size_mb"]; } if (config.showFullTorrentName !== undefined) { userData.show_full_torrent_name = config.showFullTorrentName; } else { userData.show_full_torrent_name = true; } if (config.nudityFilter) { userData.nudity_filter = config.nudityFilter; } else { userData.nudity_filter = ["Disable"]; } if (config.certificationFilter) { userData.certification_filter = config.certificationFilter; } else { userData.certification_filter = ["Disable"]; } if (config.qualityFilter) { userData.quality_filter = config.qualityFilter; } else { userData.quality_filter = []; } if (config.apiPassword) { userData.api_password = config.apiPassword; } if (config.mediaflowConfig) { userData.mediaflow_config = config.mediaflowConfig; } if (config.rpdbConfig) { userData.rpdb_config = config.rpdbConfig; } } const response = await fetchv2( `${baseUrl}/encrypt-user-data`, { 'Content-Type': 'application/json' }, "POST", JSON.stringify(userData) ); const data = await response.json(); const installationUrl = `${baseUrl}/${data.encrypted_str}/manifest.json`; return installationUrl; } catch (error) { console.error('Error generating MediaFusion URL:'+ error); throw error; } }