mirror of
https://gitlab.com/vyla-entertainment/sdk.git
synced 2026-11-12 21:27:28 -05:00
added braflix and zenox
This commit is contained in:
@@ -94,6 +94,25 @@ export const SOURCES = [
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'braflix',
|
||||
label: 'Braflix',
|
||||
sourceFile: 'braflix',
|
||||
proxyParam: 'bf',
|
||||
timeout: 25000,
|
||||
jitter: 500,
|
||||
retries: 2,
|
||||
multiUrl: true,
|
||||
skipProxy: true,
|
||||
cdnHeaders: [{
|
||||
pattern: /braflix\.dev/i,
|
||||
headers: {
|
||||
Referer: 'https://braflix.dev/',
|
||||
Origin: 'https://braflix.dev',
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'castle',
|
||||
label: 'Castle',
|
||||
@@ -725,6 +744,25 @@ export const SOURCES = [
|
||||
multiUrl: true,
|
||||
},
|
||||
|
||||
{
|
||||
key: 'zenox',
|
||||
label: 'Zenox',
|
||||
sourceFile: 'zenox',
|
||||
proxyParam: 'zx',
|
||||
timeout: 25000,
|
||||
jitter: 500,
|
||||
retries: 2,
|
||||
multiUrl: true,
|
||||
skipProxy: true,
|
||||
cdnHeaders: [{
|
||||
pattern: /zenox\.lol|hls-m3u8\.lol/i,
|
||||
headers: {
|
||||
Referer: 'https://zenox.lol/',
|
||||
Origin: 'https://zenox.lol',
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
export const HEALTH_PROBE_ID = '155';
|
||||
|
||||
80
src/sources/braflix.js
Normal file
80
src/sources/braflix.js
Normal file
@@ -0,0 +1,80 @@
|
||||
const BASE_URL = 'https://braflix.dev';
|
||||
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 = {
|
||||
Origin: BASE_URL,
|
||||
Referer: `${BASE_URL}/`,
|
||||
'User-Agent': UA,
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
};
|
||||
|
||||
const PLAYBACK_HEADERS = {
|
||||
Origin: BASE_URL,
|
||||
Referer: `${BASE_URL}/`,
|
||||
};
|
||||
|
||||
export async function getStream(args) {
|
||||
const { id, s, e } = args || {};
|
||||
const idNum = parseInt(id, 10);
|
||||
if (!idNum) return null;
|
||||
|
||||
const isTv = s != null && e != null;
|
||||
const targetSeason = isTv ? (s || 1) : 1;
|
||||
const targetEpisode = isTv ? (e || 1) : 1;
|
||||
|
||||
const path = isTv
|
||||
? `/api/play/tv/${idNum}/${targetSeason}/${targetEpisode}`
|
||||
: `/api/play/movie/${idNum}`;
|
||||
|
||||
try {
|
||||
const res = await fetch(`${BASE_URL}${path}`, {
|
||||
headers: HEADERS,
|
||||
signal: AbortSignal.timeout(10000),
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
const data = await res.json();
|
||||
|
||||
if (data?.status !== 'ready' || !data.result?.file?.stream) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rawStreamPath = data.result.file.stream;
|
||||
const fullStreamUrl = rawStreamPath.startsWith('http')
|
||||
? rawStreamPath
|
||||
: `${BASE_URL}${rawStreamPath}`;
|
||||
|
||||
const qualityRaw = String(data.result.source?.quality || '1080,720,480');
|
||||
const qualityParts = qualityRaw.split(',').map(q => q.trim()).filter(Boolean);
|
||||
const maxQ = qualityParts.reduce((acc, curr) => {
|
||||
const num = parseInt(curr, 10);
|
||||
return num > acc ? num : acc;
|
||||
}, 0);
|
||||
|
||||
const quality = maxQ > 0 ? `${maxQ}p` : 'Auto';
|
||||
const qualitySummary = qualityParts.length > 0
|
||||
? qualityParts.map(q => `${q}p`).join('/')
|
||||
: 'DASH';
|
||||
|
||||
const streamType = fullStreamUrl.includes('.mpd')
|
||||
? 'dash'
|
||||
: fullStreamUrl.includes('.m3u8')
|
||||
? 'hls'
|
||||
: 'dash';
|
||||
|
||||
const allUrls = [{
|
||||
url: fullStreamUrl,
|
||||
server: `Braflix - DASH (${qualitySummary})`,
|
||||
quality,
|
||||
type: streamType,
|
||||
headers: PLAYBACK_HEADERS,
|
||||
}];
|
||||
|
||||
return {
|
||||
url: fullStreamUrl,
|
||||
headers: PLAYBACK_HEADERS,
|
||||
allUrls,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
108
src/sources/zenox.js
Normal file
108
src/sources/zenox.js
Normal file
@@ -0,0 +1,108 @@
|
||||
const BASE_URL = 'https://zenox.lol';
|
||||
const API_URL = `${BASE_URL}/api/v1/playback/session`;
|
||||
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 = {
|
||||
'Content-Type': 'application/json',
|
||||
Origin: BASE_URL,
|
||||
Referer: `${BASE_URL}/`,
|
||||
'User-Agent': UA,
|
||||
};
|
||||
|
||||
const PLAYBACK_HEADERS = {
|
||||
Origin: BASE_URL,
|
||||
Referer: `${BASE_URL}/`,
|
||||
};
|
||||
|
||||
async function fetchServerStream(payload, srv) {
|
||||
try {
|
||||
const res = await fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: HEADERS,
|
||||
body: JSON.stringify({
|
||||
...payload,
|
||||
serverIndex: srv.index,
|
||||
serverName: srv.name,
|
||||
}),
|
||||
signal: AbortSignal.timeout(6000),
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
const data = await res.json();
|
||||
if (
|
||||
!data?.success ||
|
||||
!data?.streamUrl ||
|
||||
data.streamUrl.includes('/primary/') ||
|
||||
data.serverName?.toLowerCase() === 'primary'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const streamUrl = data.streamUrl.startsWith('http')
|
||||
? data.streamUrl
|
||||
: `${BASE_URL}${data.streamUrl}`;
|
||||
|
||||
return {
|
||||
url: streamUrl,
|
||||
server: `Zenox - ${data.serverName || srv.name}`,
|
||||
quality: 'Auto',
|
||||
type: streamUrl.includes('.m3u8') ? 'hls' : (streamUrl.includes('.mpd') ? 'dash' : 'mp4'),
|
||||
headers: PLAYBACK_HEADERS,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStream(args) {
|
||||
const { id, s, e, title, year, imdbId } = args || {};
|
||||
const idNum = parseInt(id, 10);
|
||||
if (!idNum) return null;
|
||||
|
||||
const isTv = s != null && e != null;
|
||||
const payload = {
|
||||
mediaId: idNum,
|
||||
mediaType: isTv ? 'tv' : 'movie',
|
||||
season: isTv ? (parseInt(s, 10) || 1) : 1,
|
||||
episode: isTv ? (parseInt(e, 10) || 1) : 1,
|
||||
title: title || '',
|
||||
year: String(year || ''),
|
||||
imdbId: imdbId || '',
|
||||
autoUseCommunity: false,
|
||||
isManualSwitch: true,
|
||||
};
|
||||
|
||||
const activeServers = [
|
||||
{ name: 'Vbot', index: 1 },
|
||||
{ name: 'Temporary', index: 1 },
|
||||
];
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
activeServers.map(srv => fetchServerStream(payload, srv))
|
||||
);
|
||||
|
||||
const allUrls = [];
|
||||
const seen = new Set();
|
||||
|
||||
for (const r of results) {
|
||||
if (r.status === 'fulfilled' && r.value?.url && !seen.has(r.value.url)) {
|
||||
seen.add(r.value.url);
|
||||
allUrls.push(r.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!allUrls.length) {
|
||||
const delta = await fetchServerStream(payload, { name: 'Delta', index: 0 });
|
||||
if (delta?.url && !seen.has(delta.url)) {
|
||||
seen.add(delta.url);
|
||||
allUrls.push(delta);
|
||||
}
|
||||
}
|
||||
|
||||
if (!allUrls.length) return null;
|
||||
|
||||
return {
|
||||
url: allUrls[0].url,
|
||||
headers: allUrls[0].headers,
|
||||
allUrls,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user