const express = require("express"); const { chromium } = require("playwright-core"); const cors = require("cors"); const { execSync } = require("child_process"); const axios = require("axios"); // Using Axios for better redirect handling const app = express(); const PORT = process.env.PORT || 7860; app.use(cors()); app.get("/download-links", async (req, res) => { const { url } = req.query; if (!url) { return res.status(400).json({ error: "Missing 'url' query parameter" }); } try { console.log(`Scraping: ${url}`); const downloadLinks = await getVideoLinks(url); res.json({ downloadLinks }); } catch (error) { res.status(500).json({ error: "Failed to fetch download links", details: error.message }); } }); async function getChromiumPath() { try { return execSync("which chromium-browser || which google-chrome || which chromium") .toString() .trim(); } catch { return null; // No system Chromium found } } async function getVideoLinks(downloadPageUrl) { console.log(`Opening Playwright: ${downloadPageUrl}`); const chromiumPath = await getChromiumPath(); console.log(`Chromium Path: ${chromiumPath || "Using Playwright's default"}`); const browser = await chromium.launch({ headless: true, executablePath: chromiumPath || undefined, args: ["--no-sandbox", "--disable-blink-features=AutomationControlled", "--disable-dev-shm-usage"] }); const context = await browser.newContext({ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36" }); const page = await context.newPage(); try { await page.goto(downloadPageUrl, { waitUntil: "domcontentloaded", timeout: 60000 }); // Wait for the download buttons to load await page.waitForTimeout(5000); await page.waitForSelector('a[href*="ggredi.info/download.php"]', { timeout: 60000 }); // Extract video links const videoLinks = await page.evaluate(() => Array.from(document.querySelectorAll('a[href*="ggredi.info/download.php"]')).map(link => ({ quality: link.innerText.trim(), url: link.href })) ); await browser.close(); // Convert links to final MP4 links const directDownloadLinks = {}; const promises = videoLinks .filter(link => link.quality.includes("360") || link.quality.includes("720")) .map(async link => { const finalLink = await getFinalMp4Link(link.url); if (finalLink) { directDownloadLinks[link.quality.replace(/\D/g, "") + "p"] = finalLink; } }); await Promise.all(promises); return directDownloadLinks; } catch (error) { console.error("Error extracting video links:", error.message); await browser.close(); return { "360p": "Not available", "720p": "Not available" }; } } async function getFinalMp4Link(redirectLink) { try { console.log(`Following redirect: ${redirectLink}`); const response = await axios.get(redirectLink, { maxRedirects: 5 }); const finalUrl = response.request.res.responseUrl || response.config.url; if (finalUrl && finalUrl.includes(".mp4")) { console.log(`Final MP4 Link: ${finalUrl}`); return finalUrl; } else { console.log("No valid MP4 link found."); return null; } } catch (error) { console.error("Error fetching final MP4 link:", error.message); return null; } } // Start the Express server app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));