ramarama / streams.js
SteveCelticus's picture
Upload streams.js
62d04fa verified
import cloudscraper from 'cloudscraper';
import * as cheerio from 'cheerio';
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; rv:125.0) Gecko/20100101 Firefox/125.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15',
'Mozilla/5.0 (Linux; Android 14; SM-S928U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.140 Mobile Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/123.0.6312.122'
];
async function fetchWithCloudscraper(url, retries = 3) {
function getRandomHeaders() {
return {
'User-Agent': userAgents[Math.floor(Math.random() * userAgents.length)],
'Referer': 'https://ramaorientalfansub.tv',
'Accept-Language': 'en-US,en;q=0.9',
'Upgrade-Insecure-Requests': '1',
'Cache-Control': 'no-cache',
'Pragma': 'no-cache',
'Connection': 'keep-alive',
'Accept-Encoding': 'gzip, deflate, br'
};
}
for (let i = 0; i < retries; i++) {
try {
console.log(`[${i + 1}/${retries}] Tentativo di scraping: ${url}`);
const response = await cloudscraper.get({
uri: url,
headers: getRandomHeaders(),
followAllRedirects: true,
maxRedirects: 2,
timeout: 10000,
resolveWithFullResponse: true
});
if (response.statusCode === 404) {
console.warn(`[${i + 1}/${retries}] Errore 404 per ${url}. Interrompo i tentativi.`);
return null;
}
if (response.statusCode >= 200 && response.statusCode < 300) {
console.log(`[${i + 1}/${retries}] Scraping riuscito: ${url}`);
return response.body;
} else {
console.warn(`[${i + 1}/${retries}] Errore ${response.statusCode} per ${url}. Riprovo...`);
await new Promise(resolve => setTimeout(resolve, 2000));
}
} catch (error) {
console.error(`[${i + 1}/${retries}] Errore Cloudscraper per ${url}: ${error.message}`);
if (error.message.includes('Cloudflare')) {
console.warn(`[${i + 1}/${retries}] Rilevato Cloudflare. Attendo 10 secondi...`);
await new Promise(resolve => setTimeout(resolve, 10000));
} else {
console.warn(`[${i + 1}/${retries}] Errore generico. Attendo 2 secondi...`);
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
}
console.error(`[FETCH_FAILED] Impossibile recuperare ${url} dopo ${retries} tentativi.`);
return null;
}
async function getStream(episodeLink) {
let streamUrl = null;
try {
const data = await fetchWithCloudscraper(episodeLink);
if (!data) {
console.warn(`Nessun dato ricevuto per ${episodeLink}`);
return null;
}
const $ = cheerio.load(data);
// Cerca l'iframe all'interno del div con classe 'episode-player-box'
const iframe = $('div.episode-player-box iframe');
if (iframe.length > 0) {
streamUrl = iframe.attr('src') || iframe.attr('data-src');
if (streamUrl) {
streamUrl = decodeURI(streamUrl); // Decodifica l'URL
console.log(`Trovato stream tramite iframe: ${streamUrl}`);
return streamUrl;
}
}
// Cerca nei tag video
const videoTag = $('video[name="media"] source');
if (videoTag.length > 0) {
const sourceSrc = videoTag.attr('src');
if (sourceSrc) {
streamUrl = decodeURI(sourceSrc); // Decodifica l'URL
console.log(`Trovato stream tramite tag <source>: ${streamUrl}`);
return streamUrl;
}
}
// Cerca nei link diretti
$('a[href*="streamingrof.online"]').each((_, el) => {
const href = $(el).attr('href');
if (href && href.includes('streamingrof.online')) {
streamUrl = decodeURI(href); // Decodifica l'URL
console.log(`Trovato stream tramite link diretto: ${streamUrl}`);
return false; // Interrompe il ciclo
}
});
if (!streamUrl) {
console.warn(`Nessuno stream trovato per ${episodeLink}`);
}
return streamUrl;
} catch (err) {
console.error(`Errore durante il recupero dello stream per ${episodeLink}:`, err);
return null;
}
}
export { getStream };