mirror of
https://gitlab.com/vyla-entertainment/sdk.git
synced 2026-11-12 21:27:28 -05:00
fixed fmovies4u and torrentio
This commit is contained in:
58
.js
Normal file
58
.js
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
const url = "https://s.torrentio.to/v1/sources/stream?type=movie&id=936075";
|
||||
|
||||
const headers = {
|
||||
"Accept": "text/event-stream",
|
||||
"Accept-Language": "en-US,en;q=0.9",
|
||||
"Origin": "https://stream.vidplay.to",
|
||||
"Referer": "https://stream.vidplay.to/",
|
||||
"Priority": "u=1, i",
|
||||
"Sec-CH-UA": '"Not-A.Brand";v="99", "Microsoft Edge";v="157", "Chromium";v="157"',
|
||||
"Sec-CH-UA-Mobile": "?0",
|
||||
"Sec-CH-UA-Platform": '"Windows"',
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "cross-site",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/157.0.0.0 Safari/537.36 Edg/157.0.0.0"
|
||||
};
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers
|
||||
});
|
||||
|
||||
console.log("Status:", response.status);
|
||||
console.log("Content-Type:", response.headers.get("content-type"));
|
||||
console.log("\n--- RESPONSE ---\n");
|
||||
|
||||
if (!response.ok) {
|
||||
console.log(await response.text());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.body) {
|
||||
console.log("Empty response body.");
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
|
||||
if (done) break;
|
||||
|
||||
process.stdout.write(decoder.decode(value, { stream: true }));
|
||||
}
|
||||
|
||||
process.stdout.write(decoder.decode());
|
||||
|
||||
} catch (error) {
|
||||
console.error("Request failed:", error.message);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -16,14 +16,27 @@ const PLAYBACK_HEADERS = {
|
||||
};
|
||||
|
||||
const PROVIDERS = [
|
||||
'moovie',
|
||||
'mapple',
|
||||
'anikoto',
|
||||
'anikototv',
|
||||
'anistream',
|
||||
'aniwave',
|
||||
'animex',
|
||||
'yenime',
|
||||
'otakutsu',
|
||||
'vidnest',
|
||||
'phantomflix',
|
||||
'movy',
|
||||
'cinetaro',
|
||||
'filmu',
|
||||
'streamingunity',
|
||||
'vaultplayer',
|
||||
'vixsrc',
|
||||
'ernax',
|
||||
'phantomflix',
|
||||
'moovie',
|
||||
'watchflux',
|
||||
'xtream',
|
||||
'rarefilmm'
|
||||
];
|
||||
|
||||
function extractStreams(data, providerName) {
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
const BASE_URL = 'https://s.torrentio.to';
|
||||
const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';
|
||||
|
||||
const HEADERS = {
|
||||
'User-Agent': UA,
|
||||
Referer: 'https://stream.vidplay.to/',
|
||||
Origin: 'https://stream.vidplay.to',
|
||||
Accept: 'text/event-stream, */*',
|
||||
'Accept-Language': 'en-US,en;q=0.9',
|
||||
};
|
||||
import https from 'node:https';
|
||||
|
||||
const PLAYBACK_HEADERS = {
|
||||
'User-Agent': UA,
|
||||
Referer: 'https://stream.vidplay.to/',
|
||||
Origin: 'https://stream.vidplay.to',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/157.0.0.0 Safari/537.36 Edg/157.0.0.0',
|
||||
'Referer': 'https://stream.vidplay.to/',
|
||||
'Origin': 'https://stream.vidplay.to',
|
||||
};
|
||||
|
||||
export async function getStream(args) {
|
||||
@@ -20,109 +11,120 @@ export async function getStream(args) {
|
||||
if (!id) return null;
|
||||
|
||||
const isTv = s != null && e != null;
|
||||
const targetUrl = isTv
|
||||
? `${BASE_URL}/v1/sources/stream?type=tv&id=${id}&s=${s}&e=${e}`
|
||||
: `${BASE_URL}/v1/sources/stream?type=movie&id=${id}`;
|
||||
const requestPath = isTv
|
||||
? `/v1/sources/stream?type=tv&id=${id}&s=${s}&e=${e}`
|
||||
: `/v1/sources/stream?type=movie&id=${id}`;
|
||||
|
||||
try {
|
||||
const res = await fetch(targetUrl, {
|
||||
headers: HEADERS,
|
||||
signal: AbortSignal.timeout(args?.config?.timeout || 25000),
|
||||
});
|
||||
return new Promise((resolve) => {
|
||||
const options = {
|
||||
hostname: 's.torrentio.to',
|
||||
port: 443,
|
||||
path: requestPath,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'text/event-stream',
|
||||
'Accept-Language': 'en-US,en;q=0.9',
|
||||
'Origin': 'https://stream.vidplay.to',
|
||||
'Referer': 'https://stream.vidplay.to/',
|
||||
'Sec-CH-UA': '"Not-A.Brand";v="99", "Microsoft Edge";v="157", "Chromium";v="157"',
|
||||
'Sec-CH-UA-Mobile': '?0',
|
||||
'Sec-CH-UA-Platform': '"Windows"',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Site': 'cross-site',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/157.0.0.0 Safari/537.36 Edg/157.0.0.0',
|
||||
'Connection': 'keep-alive',
|
||||
},
|
||||
timeout: 25000,
|
||||
};
|
||||
|
||||
if (!res.ok || !res.body) return null;
|
||||
|
||||
const reader = res.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = '';
|
||||
const allUrls = [];
|
||||
const seen = new Set();
|
||||
let buffer = '';
|
||||
let resolved = false;
|
||||
|
||||
outer: while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
const done = (result) => {
|
||||
if (resolved) return;
|
||||
resolved = true;
|
||||
try { req.destroy(); } catch { }
|
||||
resolve(result);
|
||||
};
|
||||
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const lines = buffer.split('\n');
|
||||
buffer = lines.pop() || '';
|
||||
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed === 'event: done') {
|
||||
try { await reader.cancel(); } catch { }
|
||||
break outer;
|
||||
}
|
||||
|
||||
if (trimmed.startsWith('data: ')) {
|
||||
try {
|
||||
const data = JSON.parse(trimmed.slice(6));
|
||||
if (Array.isArray(data?.sources)) {
|
||||
for (const src of data.sources) {
|
||||
if (!src?.url || seen.has(src.url)) continue;
|
||||
seen.add(src.url);
|
||||
|
||||
const provName = src.provider?.name || data.provider?.name || 'Server';
|
||||
const rawQ = src.quality ? String(src.quality).trim() : 'Auto';
|
||||
const quality = /^\d+$/i.test(rawQ)
|
||||
? `${rawQ}p`
|
||||
: /^\d+p$/i.test(rawQ)
|
||||
? rawQ.toLowerCase()
|
||||
: rawQ;
|
||||
|
||||
const type = src.type || (src.url.includes('.m3u8') ? 'hls' : (src.url.includes('.mpd') ? 'dash' : 'mp4'));
|
||||
|
||||
allUrls.push({
|
||||
url: src.url,
|
||||
server: `Torrentio - ${provName}`,
|
||||
quality,
|
||||
type,
|
||||
headers: PLAYBACK_HEADERS,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
const req = https.request(options, (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
return done(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.trim().startsWith('data: ')) {
|
||||
try {
|
||||
const data = JSON.parse(buffer.trim().slice(6));
|
||||
if (Array.isArray(data?.sources)) {
|
||||
for (const src of data.sources) {
|
||||
if (!src?.url || seen.has(src.url)) continue;
|
||||
seen.add(src.url);
|
||||
res.setEncoding('utf8');
|
||||
|
||||
const provName = src.provider?.name || data.provider?.name || 'Server';
|
||||
const rawQ = src.quality ? String(src.quality).trim() : 'Auto';
|
||||
const quality = /^\d+$/i.test(rawQ)
|
||||
? `${rawQ}p`
|
||||
: /^\d+p$/i.test(rawQ)
|
||||
? rawQ.toLowerCase()
|
||||
: rawQ;
|
||||
res.on('data', (chunk) => {
|
||||
buffer += chunk;
|
||||
const lines = buffer.split('\n');
|
||||
buffer = lines.pop() || '';
|
||||
|
||||
const type = src.type || (src.url.includes('.m3u8') ? 'hls' : (src.url.includes('.mpd') ? 'dash' : 'mp4'));
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
|
||||
allUrls.push({
|
||||
url: src.url,
|
||||
server: `Torrentio - ${provName}`,
|
||||
quality,
|
||||
type,
|
||||
headers: PLAYBACK_HEADERS,
|
||||
});
|
||||
if (trimmed.startsWith('data: ')) {
|
||||
try {
|
||||
const data = JSON.parse(trimmed.slice(6));
|
||||
if (Array.isArray(data?.sources)) {
|
||||
for (const src of data.sources) {
|
||||
if (!src?.url || seen.has(src.url)) continue;
|
||||
seen.add(src.url);
|
||||
|
||||
const provName = src.provider?.name || data.provider?.name || 'Server';
|
||||
const rawQ = src.quality ? String(src.quality).trim() : 'Auto';
|
||||
const quality = /^\d+$/i.test(rawQ) ? `${rawQ}p` : rawQ;
|
||||
const type = src.type || (src.url.includes('.m3u8') ? 'hls' : 'mp4');
|
||||
|
||||
allUrls.push({
|
||||
url: src.url,
|
||||
server: `Torrentio - ${provName}`,
|
||||
quality,
|
||||
type,
|
||||
headers: PLAYBACK_HEADERS,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
|
||||
if (allUrls.length > 0) {
|
||||
return done({
|
||||
url: allUrls[0].url,
|
||||
headers: allUrls[0].headers,
|
||||
allUrls,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
});
|
||||
|
||||
if (!allUrls.length) return null;
|
||||
res.on('end', () => {
|
||||
if (allUrls.length > 0) {
|
||||
done({
|
||||
url: allUrls[0].url,
|
||||
headers: allUrls[0].headers,
|
||||
allUrls,
|
||||
});
|
||||
} else {
|
||||
done(null);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
url: allUrls[0].url,
|
||||
headers: allUrls[0].headers,
|
||||
allUrls,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
res.on('error', () => {
|
||||
done(allUrls.length ? { url: allUrls[0].url, headers: allUrls[0].headers, allUrls } : null);
|
||||
});
|
||||
});
|
||||
|
||||
req.on('timeout', () => {
|
||||
done(allUrls.length ? { url: allUrls[0].url, headers: allUrls[0].headers, allUrls } : null);
|
||||
});
|
||||
|
||||
req.on('error', () => {
|
||||
done(allUrls.length ? { url: allUrls[0].url, headers: allUrls[0].headers, allUrls } : null);
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user