diff --git a/src/controllers/streamInfo.controller.js b/src/controllers/streamInfo.controller.js index 5952f78..1bcd855 100644 --- a/src/controllers/streamInfo.controller.js +++ b/src/controllers/streamInfo.controller.js @@ -5,9 +5,12 @@ export const getStreamInfo = async (req, res, fallback = false) => { const input = req.query.id; const server = req.query.server; const type = req.query.type; - const match = input.match(/ep=(\d+)/); - if (!match) throw new Error("Invalid URL format"); - const finalId = match[1]; + const ep = req.query.ep; + + let finalId = ep || input?.match(/ep=(\d+)/)?.[1] || input; + + if (!finalId) throw new Error("Invalid URL format: episode ID missing"); + const streamingInfo = await extractStreamingInfo(finalId, server, type, fallback); return streamingInfo; } catch (e) { diff --git a/src/extractors/streamInfo.extractor.js b/src/extractors/streamInfo.extractor.js index c7123c7..48bb86a 100644 --- a/src/extractors/streamInfo.extractor.js +++ b/src/extractors/streamInfo.extractor.js @@ -59,7 +59,26 @@ async function extractStreamingInfo(id, name, type, fallback) { type, fallback ); - return { streamingLink, servers }; + + if (!streamingLink) { + return { streamingLink: [], servers }; + } + + return { + streamingLink: [ + { + link: streamingLink.link.file, + type: streamingLink.link.type, + server: streamingLink.server, + iframe: streamingLink.iframe, + }, + ], + tracks: streamingLink.tracks, + intro: streamingLink.intro, + outro: streamingLink.outro, + server: streamingLink.server, + servers, + }; } catch (error) { console.error("An error occurred:", error); return { streamingLink: [], servers: [] }; diff --git a/src/parsers/decryptors/decrypt_v1.decryptor.js b/src/parsers/decryptors/decrypt_v1.decryptor.js index 6721c37..91963a5 100644 --- a/src/parsers/decryptors/decrypt_v1.decryptor.js +++ b/src/parsers/decryptors/decrypt_v1.decryptor.js @@ -60,6 +60,7 @@ export async function decryptSources_v1(epID, id, name, type, fallback) { try { let decryptedSources = null; let iframeURL = null; + let ajaxLink = null; if (fallback) { const fallback_server = ["hd-1", "hd-3"].includes(name.toLowerCase()) @@ -90,41 +91,46 @@ export async function decryptSources_v1(epID, id, name, type, fallback) { decryptedSources = decryptedData; } else { const { data: sourcesData } = await axios.get( - `https://${v1_base_url}/ajax/v2/episode/sources?id=${id}`, - ); - - const ajaxLink = sourcesData?.link; - if (!ajaxLink) throw new Error("Missing link in sourcesData"); - console.log(ajaxLink); - const sourceIdMatch = /\/([^/?]+)\?/.exec(ajaxLink); - const sourceId = sourceIdMatch?.[1]; - if (!sourceId) throw new Error("Unable to extract sourceId from link"); - const new_url = `https://megacloud.blog/embed-2/v3/e-1/${sourceId}?k=1`; - const { data: stream_data } = await axios.post( - "https://megacloud.zenime.site/get-sources", - { - embedUrl: new_url, - }, + `https://${v4_base_url}/ajax/episode/sources?id=${id}`, { headers: { - "Content-Type": "application/json", + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", }, }, ); - decryptedSources = stream_data; - // const baseUrlMatch = ajaxLink.match( - // /^(https?:\/\/[^\/]+(?:\/[^\/]+){3})/, - // ); - // if (!baseUrlMatch) throw new Error("Could not extract base URL"); - // const baseUrl = baseUrlMatch[1]; + ajaxLink = sourcesData?.link; + if (!ajaxLink) throw new Error("Missing link in sourcesData"); + iframeURL = ajaxLink; - // iframeURL = `${baseUrl}/${sourceId}?k=1&autoPlay=0&oa=0&asi=1`; + const sourceIdMatch = /\/([^/?]+)\?/.exec(ajaxLink); + const sourceId = sourceIdMatch?.[1]; + if (!sourceId) throw new Error("Unable to extract sourceId from link"); - // const { data: rawSourceData } = await axios.get( - // `${baseUrl}/getSources?id=${sourceId}`, - // ); - // decryptedSources = rawSourceData; + const baseUrlMatch = ajaxLink.match(/^(https?:\/\/[^\/]+(?:\/[^\/]+){3})/); + if (!baseUrlMatch) throw new Error("Could not extract base URL"); + const baseUrl = baseUrlMatch[1]; + + const sourcesUrl = `${baseUrl}/getSources?id=${sourceId}`; + + const { data: directData } = await axios.get(sourcesUrl, { + headers: { + Accept: "*/*", + "X-Requested-With": "XMLHttpRequest", + Referer: `${ajaxLink}&autoPlay=1&oa=0&asi=1`, + "Accept-Language": "en-US,en;q=0.9", + "Accept-Encoding": "gzip, deflate, br", + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", + Origin: baseUrl.match(/^https?:\/\/[^\/]+/)[0], + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + }, + }); + + decryptedSources = directData; } return { @@ -133,7 +139,9 @@ export async function decryptSources_v1(epID, id, name, type, fallback) { link: { file: fallback ? (decryptedSources?.sources?.file ?? "") - : (decryptedSources?.sources?.[0].file ?? ""), + : (Array.isArray(decryptedSources?.sources) + ? (decryptedSources?.sources?.[0]?.file ?? "") + : (typeof decryptedSources?.sources === "object" ? (decryptedSources?.sources?.file ?? "") : "")), type: "hls", }, tracks: decryptedSources.tracks ?? [], @@ -145,7 +153,7 @@ export async function decryptSources_v1(epID, id, name, type, fallback) { } catch (error) { console.error( `Error during decryptSources_v1(${id}, epID=${epID}, server=${name}):`, - error.message, + error.response ? `${error.response.status} - ${error.response.statusText}` : error.message, ); return null; }