Skip to content

stuck to find .m3u8 file from vidsrc #24

Description

@flex-drivee

Hi sir, I hope you're doing well. I’ve been working on extracting .m3u8 files from Vidsrc and came across your repository. I went through it, and it was really helpful.
I’m trying to fetch the URL but haven’t been able to get it to work. Could you please help me understand where I might be going wrong?
I’m sharing my code below—if you could take a look and guide me, I’d really appreciate it. Thanks a lot.

`const express = require('express');
const cors = require('cors');
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const cheerio = require('cheerio');

puppeteer.use(StealthPlugin());

const app = express();
const PORT = 3001;

app.use(cors());

// -------- CONFIG --------
const BASE_DOMAIN = 'https://vidsrc.xyz';
const CHROME_PATH = "C:\Program Files\Google\Chrome\Application\chrome.exe";
const VIDEO_HOST_KEYWORDS = ["superembed", "vidplay", "filemoon", "2embed", "cloudnestra"];
const COMMON_HEADERS = {
'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',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8',
'Accept-Language': 'en-US,en;q=0.9'
};

const wait = (ms) => new Promise(res => setTimeout(res, ms));

// ==========================================
// 🔐 DECODER LIBRARY
// ==========================================
const Decoders = {
SqmOaLsKHv7vWtli: (x) => { try { return atob(x); } catch(e) { return null; } },
bMGyx71TzQLfdonN: (x) => { var a=3,b=[];for(var i=0;i<x.length;i+=a)b.push(x.slice(i,i+a));return b.reverse().join("")},
Iry9MQXnLs: (x) => { const k="pWB9V)[*4I`nJpp?ozyBdbr9yt!_n4u";let r="";const h=x.match(/.{1,2}/g).map(c=>String.fromCharCode(parseInt(c,16))).join("");for(let i=0;i<h.length;i++)r+=String.fromCharCode(h.charCodeAt(i)^k.charCodeAt(i%k.length));let f="";for(let i=0;i<r.length;i++)f+=String.fromCharCode(r.charCodeAt(i)-3);return atob(f);},
IGLImMhWrI: (x) => { const r=x.split("").reverse().join("");const n=r.replace(/[a-zA-Z]/g,c=>String.fromCharCode(c.charCodeAt(0)+(c.toLowerCase()<"n"?13:-13)));return atob(n.split("").reverse().join(""));},
GTAxQyTyBx: (x) => { const r=x.split("").reverse().join("");let f="";for(let i=0;i<r.length;i+=2)f+=r[i];return atob(f);},
C66jPHx8qu: (x) => { const r=x.split("").reverse().join("");const k="X9a(O;FMV2-7VO5x;Ao:dN1NoFs?j,";const h=r.match(/.{1,2}/g).map(c=>String.fromCharCode(parseInt(c,16))).join("");let f="";for(let i=0;i<h.length;i++)f+=String.fromCharCode(h.charCodeAt(i)^k.charCodeAt(i%k.length));return f;},
MyL1IRSfHe: (x) => { const r=x.split("").reverse().join("");let s="";for(let i=0;i<r.length;i++)s+=String.fromCharCode(r.charCodeAt(i)-1);let f="";for(let i=0;i<s.length;i+=2)f+=String.fromCharCode(parseInt(s.substr(i,2),16));return f;},
detdj7JHiK: (x) => { const t=x.slice(10,-16);const k="3SAY
#%Y(V%>5d/Yg"$G[Lh1rK4a;7ok";const d=atob(t);const e=k.repeat(Math.ceil(d.length/k.length)).substring(0,d.length);let f="";for(let i=0;i<d.length;i++)f+=String.fromCharCode(d.charCodeAt(i)^e.charCodeAt(i));return f;},
nZlUnj2VSo: (x) => { const m={x:"a",y:"b",z:"c",a:"d",b:"e",c:"f",d:"g",e:"h",f:"i",g:"j",h:"k",i:"l",j:"m",k:"n",l:"o",m:"p",n:"q",o:"r",p:"s",q:"t",r:"u",s:"v",t:"w",u:"x",v:"y",w:"z",X:"A",Y:"B",Z:"C",A:"D",B:"E",C:"F",D:"G",E:"H",F:"I",G:"J",H:"K",I:"L",J:"M",K:"N",L:"O",M:"P",N:"Q",O:"R",P:"S",Q:"T",R:"U",S:"V",T:"W",U:"X",V:"Y",W:"Z"};return x.replace(/[xyzabcdefghijklmnopqrstuvwXYZABCDEFGHIJKLMNOPQRSTUVW]/g,c=>m[c]);},
laM1dAi3vO: (x) => { const r=x.split("").reverse().join("");const b=atob(r.replace(/-/g,"+").replace(//g,"/"));let f="";for(let i=0;i<b.length;i++)f+=String.fromCharCode(b.charCodeAt(i)-5);return f;},
GuxKGDsA2T: (x) => { const r=x.split("").reverse().join("");const b=atob(r.replace(/-/g,"+").replace(/
/g,"/"));let f="";for(let i=0;i<b.length;i++)f+=String.fromCharCode(b.charCodeAt(i)-7);return f;},
LXVUMCoAHJ: (x) => { const r=x.split("").reverse().join("");const b=atob(r.replace(/-/g,"+").replace(/_/g,"/"));let f="";for(let i=0;i<b.length;i++)f+=String.fromCharCode(b.charCodeAt(i)-3);return f;}
};

function bruteForceDecode(hash) {
for (const [name, func] of Object.entries(Decoders)) {
try {
const result = func(hash);
if (result && result.startsWith('http')) {
console.log([Backend] 🔓 Decoded using ${name}: ${result});
return result;
}
} catch (e) {}
}
return null;
}

// 🛠️ HELPER: Fetch RPC using EXISTING Page (Cookies!)
async function handleProRpc(page, rcpUrl, referer) {
console.log([Backend] 🔓 Fetching RPC (In-Context): ${rcpUrl});
try {
// Use the page's context to fetch. No new tab.
const html = await page.evaluate(async (url, ref) => {
try {
const r = await fetch(url, { headers: { 'Referer': ref } });
return await r.text();
} catch (e) { return null; }
}, rcpUrl, referer);

    if (!html) {
        console.log("[Backend] ❌ Fetch returned null.");
        return null;
    }

    // 1. JS Redirect
    const match = html.match(/window\.location\.href\s*=\s*["']([^"']+)["']/);
    if (match && match[1].startsWith('http')) {
         console.log(`[Backend] ✅ Found JS Redirect!`);
         return match[1];
    }

    // 2. Hidden Hash
    const $ = cheerio.load(html);
    const hidden = $('#hidden').attr('data-hash');
    if (hidden) {
        console.log("[Backend] 🕵️ Found Hidden Hash. Brute-forcing...");
        const decoded = bruteForceDecode(hidden);
        if (decoded) {
            console.log(`[Backend] ✅ Cracked Hash!`);
            return decoded;
        } else {
            console.log("[Backend] ❌ Hash found but decoding failed.");
        }
    } else {
        console.log("[Backend] ❌ No #hidden element in response.");
    }

} catch (e) {
    console.log(`[Backend] ⚠️ Error: ${e.message}`);
}
return null;

}

function isStreamUrl(url) {
if (!url) return false;
const lower = url.toLowerCase();
if (!VIDEO_HOST_KEYWORDS.some(k => lower.includes(k))) return false;
if (lower.match(/.(js|css|png|jpg|svg|ico|woff|json)(?|$)/)) return false;
return lower.includes('.m3u8') || lower.includes('.mp4') || //(e|embed|play|v)//.test(lower);
}

function isRpcUrl(url) {
if (!url) return false;
const lower = url.toLowerCase();
return VIDEO_HOST_KEYWORDS.some(k => lower.includes(k)) && lower.includes('/rcp/');
}

app.get('/api/resolve', async (req, res) => {
const { imdb_id } = req.query;
console.log(\n[Backend] 🔍 Starting Resolution for: ${imdb_id} (In-Context Decoder));

let browser;
const state = {
found: false,
finalUrl: null,
rpcUrl: null
};

try {
browser = await puppeteer.launch({
headless: false,
executablePath: CHROME_PATH,
ignoreDefaultArgs: ['--enable-automation'],
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-blink-features=AutomationControlled',
'--start-maximized',
'--disable-features=IsolateOrigins,site-per-process'
]
});

const page = (await browser.pages())[0];
await page.setViewport({ width: 1920, height: 1080 });
await page.setRequestInterception(true);

page.on('request', req => {
    if (state.found) { req.continue(); return; }
    const type = req.resourceType();
    if (['image', 'font'].includes(type)) { req.abort(); return; }
    if (isStreamUrl(req.url())) {
         console.log(`[Backend] 🔥 FOUND GOLD DIRECTLY: ${req.url()}`);
         state.finalUrl = req.url();
         state.found = true;
    }
    req.continue();
});

page.on('response', async (response) => {
    if (state.found) return;
    const url = response.url();
    if (isRpcUrl(url) && response.status() === 200 && !state.rpcUrl) {
        console.log(`[Backend] 🕵️ Captured RPC: ${url}`);
        state.rpcUrl = url;
    }
});

// --- STEP 1: VISIT ---
const embedUrl = `${BASE_DOMAIN}/embed/movie/${imdb_id}`;
console.log(`[Backend] Visiting: ${embedUrl}`);

await page.setExtraHTTPHeaders({ ...COMMON_HEADERS, Referer: BASE_DOMAIN });
await page.goto(embedUrl, { waitUntil: 'domcontentloaded', timeout: 30000 });
await wait(2000);

// ⚡ PRO SHORT CIRCUIT (Using SAME page)
if (state.rpcUrl && !state.found) {
    console.log("[Backend] ⚡ RPC Found! Attempting IN-CONTEXT Decode...");
    
    // Use the EXISTING 'page' to fetch (inherits cookies!)
    const decoded = await handleProRpc(page, state.rpcUrl, embedUrl);
    
    if (decoded && decoded.startsWith('http')) {
        state.finalUrl = decoded;
        state.found = true;
        console.log(`[Backend] ✅ Decoded Successfully!`);
    }
}

await browser.close();

if (!state.found) throw new Error("All servers failed.");

let final = state.finalUrl;
if (final.includes('?')) final = final.split('?')[0];
if (!final.startsWith('http')) final = 'https://' + final;

console.log(`[Backend] 🔓 Final Stream URL: ${final}`);
res.json({ status: 'success', streamUrl: final });

} catch (err) {
console.error('[Backend] 💥 Error:', err.message);
if (browser) try { await browser.close(); } catch (e) {}
res.status(500).json({ error: err.message });
}
});

app.listen(PORT, () => {
console.log(🚀 In-Context Scraper running on http://localhost:${PORT});
});`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions