mirror of
https://gitlab.com/vyla-entertainment/sdk.git
synced 2026-11-14 14:17:35 -05:00
removed vidora, and bcine. fixed vidlink
This commit is contained in:
@@ -56,24 +56,6 @@ export const SOURCES = [
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'bcine',
|
||||
label: 'Bcine',
|
||||
sourceFile: 'bcine',
|
||||
proxyParam: 'bc',
|
||||
timeout: 25000,
|
||||
jitter: 500,
|
||||
retries: 2,
|
||||
multiUrl: true,
|
||||
cdnHeaders: [{
|
||||
pattern: /1embed\.cc|videasy\.to/i,
|
||||
headers: {
|
||||
Referer: 'https://bcine.ru/',
|
||||
Origin: 'https://bcine.ru',
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'cinemaarmy',
|
||||
label: 'CinemaArmy',
|
||||
@@ -361,14 +343,6 @@ export const SOURCES = [
|
||||
jitter: 500,
|
||||
retries: 2,
|
||||
multiUrl: true,
|
||||
skipProxy: true,
|
||||
cdnHeaders: [{
|
||||
pattern: /hakunaymatata\.com/i,
|
||||
headers: {
|
||||
Referer: 'https://net79.cc/',
|
||||
Origin: 'https://net79.cc',
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
@@ -493,7 +467,16 @@ export const SOURCES = [
|
||||
jitter: 500,
|
||||
retries: 1,
|
||||
multiUrl: true,
|
||||
skipProxy: true,
|
||||
cdnHeaders: [{
|
||||
pattern: /vidcore\.io/i,
|
||||
headers: {
|
||||
Referer: 'https://vidcore.io/',
|
||||
Origin: 'https://vidcore.io',
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'vidfast',
|
||||
label: 'VidFast',
|
||||
@@ -505,25 +488,6 @@ export const SOURCES = [
|
||||
multiUrl: true,
|
||||
},
|
||||
|
||||
{
|
||||
key: 'vidora',
|
||||
label: 'Vidora',
|
||||
sourceFile: 'vidora',
|
||||
proxyParam: 'vdra',
|
||||
timeout: 25000,
|
||||
jitter: 500,
|
||||
retries: 2,
|
||||
multiUrl: true,
|
||||
skipProxy: true,
|
||||
cdnHeaders: [{
|
||||
pattern: /rousav\.tech|vidbolt\.xyz|vidrift\.in|goldenkite\.top|ravok\.buzz/i,
|
||||
headers: {
|
||||
Referer: 'https://vidora-3l2w.onrender.com/',
|
||||
Origin: 'https://vidora-3l2w.onrender.com',
|
||||
},
|
||||
}],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'vidlink',
|
||||
label: 'Vidlink',
|
||||
@@ -532,7 +496,6 @@ export const SOURCES = [
|
||||
timeout: 20000,
|
||||
jitter: 500,
|
||||
retries: 2,
|
||||
skipProxy: true,
|
||||
multiUrl: true,
|
||||
},
|
||||
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
import { USER_AGENT } from '../utils/helpers.js';
|
||||
|
||||
const _sInit = [23, 27, 30, 31, 86, 28, 19, 86, 9, 18, 19, 21, 26, 27, 86, 120, 114, 120, 116, 86, 9, 18, 19, 21, 26, 27, 122, 89, 25, 23];
|
||||
const _vParam = `_v=${(_sInit[15] ^ 0x5a)}${(_sInit[16] ^ 0x5a)}${(_sInit[17] ^ 0x5a)}${(_sInit[18] ^ 0x5a)}`;
|
||||
|
||||
const nD = '4860ac8bfddb';
|
||||
const aD = '224eff10e662e9635c9f671cf46351dcd69af42b1edd56f5e5fa21751f44b9c8';
|
||||
const Ls = [17, 91, 203, 44, 8, 177, 62, 239, 119, 3, 154, 81, 28, 210, 101, 7];
|
||||
const wa = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
||||
|
||||
const SERVERS = [
|
||||
{ id: 'NIGHT', endpoint: '/server/night' },
|
||||
{ id: 'EMP', endpoint: '/server/emp' },
|
||||
{ id: 'MAIN', endpoint: '/server/vidsrc' }
|
||||
];
|
||||
|
||||
const CORS_PROXY = 'https://eve.pstream.cfd';
|
||||
let cachedToken = null;
|
||||
let tokenExpiry = 0;
|
||||
|
||||
function ab(e) {
|
||||
let t = e >>> 0;
|
||||
t ^= t >>> 16;
|
||||
t = Math.imul(t, 2146121005) >>> 0;
|
||||
t ^= t >>> 15;
|
||||
t = Math.imul(t, 2221713035) >>> 0;
|
||||
return (t ^ (t >>> 16)) >>> 0;
|
||||
}
|
||||
|
||||
function sD(e) {
|
||||
const t = new TextEncoder().encode(aD);
|
||||
const r = Math.max(32, Math.min(128, e + 17));
|
||||
const n = new Uint8Array(r);
|
||||
let a = 2166136261;
|
||||
for (let s = 0; s < r; s += 1) {
|
||||
a ^= t[s % t.length] ?? s;
|
||||
a = ab((a + Ls[s % Ls.length] + ((2654435761 * s) >>> 0)) >>> 0);
|
||||
n[s] = a & 255;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
function iD(e) {
|
||||
let t = '';
|
||||
for (let r = 0; r < e.length; r += 3) {
|
||||
const n = e[r];
|
||||
const a = e[r + 1];
|
||||
const s = e[r + 2];
|
||||
t += wa[n >>> 2];
|
||||
t += wa[((3 & n) << 4) | ((a ?? 0) >>> 4)];
|
||||
if (a === undefined) break;
|
||||
t += wa[((15 & a) << 2) | ((s ?? 0) >>> 6)];
|
||||
if (s === undefined) break;
|
||||
t += wa[63 & s];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
function generateDirectHlsUrl(id, s, e) {
|
||||
const isTv = s != null && e != null;
|
||||
const tmdbId = Math.floor(Number(id));
|
||||
const season = isTv ? Math.floor(Number(s || 1)) : 0;
|
||||
const episode = isTv ? Math.floor(Number(e || 1)) : 0;
|
||||
|
||||
const str = `${nD}:${isTv ? 's' : 'm'}:${tmdbId}:${season}:${episode}`;
|
||||
const a = new TextEncoder().encode(str);
|
||||
const sArr = sD(a.length);
|
||||
const i = new Uint8Array(a.length + 2);
|
||||
i[0] = a.length & 255;
|
||||
i[1] = (a.length >>> 8) & 255;
|
||||
let o = (2654435769 ^ a.length) >>> 0;
|
||||
for (let l = 0; l < a.length; l += 1) {
|
||||
o = ab((o + sArr[l % sArr.length] + Ls[l % Ls.length] + l) >>> 0);
|
||||
i[l + 2] = (a[l] ^ (255 & o)) ^ sArr[(7 * l + 3) % sArr.length];
|
||||
}
|
||||
|
||||
return `https://glendale-plumbing.com/c/v1/${iD(i)}/master.m3u8`;
|
||||
}
|
||||
|
||||
async function fetchInternalToken() {
|
||||
if (cachedToken && Date.now() < tokenExpiry) return cachedToken;
|
||||
try {
|
||||
const res = await fetch('https://1embed.cc/api/token', {
|
||||
headers: {
|
||||
'User-Agent': USER_AGENT,
|
||||
'Referer': 'https://1embed.cc/',
|
||||
'Accept': 'application/json, text/plain, */*'
|
||||
},
|
||||
signal: AbortSignal.timeout(4000)
|
||||
});
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
if (data?.token) {
|
||||
cachedToken = data.token;
|
||||
tokenExpiry = Date.now() + 1800 * 1000;
|
||||
return cachedToken;
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
|
||||
try {
|
||||
const proxiedUrl = `${CORS_PROXY}/?destination=${encodeURIComponent('https://1embed.cc/api/token')}`;
|
||||
const res = await fetch(proxiedUrl, {
|
||||
headers: {
|
||||
'X-Referer': 'https://1embed.cc/',
|
||||
'X-User-Agent': USER_AGENT
|
||||
},
|
||||
signal: AbortSignal.timeout(4000)
|
||||
});
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
if (data?.token) {
|
||||
cachedToken = data.token;
|
||||
tokenExpiry = Date.now() + 1800 * 1000;
|
||||
return cachedToken;
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export async function getStream(args) {
|
||||
const { id, s, e, clientIP } = args;
|
||||
const isTv = s != null && e != null;
|
||||
const isMovie = !isTv;
|
||||
const allUrls = [];
|
||||
|
||||
const directHlsUrl = generateDirectHlsUrl(id, s, e);
|
||||
const masterUrlWithMark = `${directHlsUrl}?${_vParam}`;
|
||||
|
||||
allUrls.push({
|
||||
url: masterUrlWithMark,
|
||||
server: 'Bcine (Direct Master)',
|
||||
quality: 'Auto',
|
||||
type: 'hls',
|
||||
headers: {
|
||||
'User-Agent': USER_AGENT,
|
||||
'Referer': 'https://bcine.ru/',
|
||||
'Origin': 'https://bcine.ru',
|
||||
...(clientIP && { 'X-Forwarded-For': clientIP })
|
||||
}
|
||||
});
|
||||
|
||||
const token = await fetchInternalToken();
|
||||
|
||||
await Promise.allSettled(
|
||||
SERVERS.map(async (server) => {
|
||||
const query = isTv
|
||||
? `id=${id}?type=tv&s=${s || 1}&e=${e || 1}`
|
||||
: `id=${id}?type=movie`;
|
||||
|
||||
const stParam = token ? `&_st=${token}` : '';
|
||||
const targetUrl = `https://1embed.cc${server.endpoint}/${query}${stParam}`;
|
||||
|
||||
const headers = {
|
||||
'User-Agent': USER_AGENT,
|
||||
'Referer': 'https://bcine.ru/',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
...(token && { 'X-Stream-Token': token }),
|
||||
...(clientIP && { 'X-Forwarded-For': clientIP })
|
||||
};
|
||||
|
||||
let res = await fetch(targetUrl, { headers, signal: AbortSignal.timeout(5000) }).catch(() => null);
|
||||
if (!res || !res.ok) {
|
||||
const proxiedUrl = `${CORS_PROXY}/?destination=${encodeURIComponent(targetUrl)}`;
|
||||
res = await fetch(proxiedUrl, {
|
||||
headers: {
|
||||
'X-Referer': 'https://bcine.ru/',
|
||||
'X-User-Agent': USER_AGENT
|
||||
},
|
||||
signal: AbortSignal.timeout(5000)
|
||||
}).catch(() => null);
|
||||
}
|
||||
|
||||
if (res && res.ok) {
|
||||
try {
|
||||
const data = await res.json();
|
||||
if (data && data.success !== false) {
|
||||
const streamUrl = data.streams?.proxy_m3u8 || data.streams?.raw_m3u8 || data.streams?.m3u8 || data.streamUrl;
|
||||
if (streamUrl && typeof streamUrl === 'string') {
|
||||
const urlWithMark = streamUrl.includes('?') ? `${streamUrl}&${_vParam}` : `${streamUrl}?${_vParam}`;
|
||||
allUrls.push({
|
||||
url: urlWithMark,
|
||||
server: `Bcine (${data.selectedSource || data.provider || server.id})`,
|
||||
quality: 'Auto',
|
||||
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
||||
headers: {
|
||||
'User-Agent': USER_AGENT,
|
||||
'Referer': 'https://bcine.ru/',
|
||||
'Origin': 'https://bcine.ru'
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return allUrls.length ? { allUrls } : null;
|
||||
}
|
||||
@@ -7,22 +7,70 @@ export async function getStream({ id, s, e }) {
|
||||
try {
|
||||
const encData = await fetchJson(`https://enc-dec.app/api/enc-vidlink?text=${id}`, { signal: AbortSignal.timeout(6000) });
|
||||
if (encData?.status !== 200 || !encData?.result) return null;
|
||||
const data = await fetchJson(s ? `${BASE}/api/b/tv/${encData.result}/${s}/${e || 1}` : `${BASE}/api/b/movie/${encData.result}`, { headers: HEADERS, signal: AbortSignal.timeout(10000) });
|
||||
const stream = data?.stream;
|
||||
if (!stream) return null;
|
||||
if (stream.type === 'file' && stream.qualities) {
|
||||
let picked = null;
|
||||
for (const q of ['1080', '720', '480', '360']) if (stream.qualities[q]?.url) { picked = stream.qualities[q].url; break; }
|
||||
if (!picked) picked = stream.qualities[Object.keys(stream.qualities)[0]]?.url;
|
||||
if (picked) return { allUrls: [{ url: picked, type: 'mp4', audio: 'sub', server: 'Vidlink', skipHlsCheck: true, skipCache: true }] };
|
||||
} else if (stream.playlist) {
|
||||
return { allUrls: [{ url: stream.playlist, type: 'hls', audio: 'sub', server: 'Vidlink', skipHlsCheck: true, skipCache: true }] };
|
||||
|
||||
const basePath = s ? `${BASE}/api/b/tv/${encData.result}/${s}/${e || 1}` : `${BASE}/api/b/movie/${encData.result}`;
|
||||
const responses = await Promise.allSettled([
|
||||
fetchJson(basePath, { headers: HEADERS, signal: AbortSignal.timeout(10000) }),
|
||||
fetchJson(`${basePath}?multiLang=0`, { headers: HEADERS, signal: AbortSignal.timeout(10000) })
|
||||
]);
|
||||
|
||||
const streamList = [];
|
||||
const seenUrls = new Set();
|
||||
const seenSubs = new Set();
|
||||
|
||||
for (const res of responses) {
|
||||
if (res.status !== 'fulfilled' || !res.value?.stream) continue;
|
||||
const stream = res.value.stream;
|
||||
|
||||
if (stream.playlist && !seenUrls.has(stream.playlist)) {
|
||||
seenUrls.add(stream.playlist);
|
||||
const isDash = stream.type === 'dash' || stream.deliveryType === 'dash' || stream.playlist.includes('.mpd');
|
||||
streamList.push({
|
||||
url: stream.playlist,
|
||||
quality: stream.playbackMetadata?.resolutions?.[0] ? `${stream.playbackMetadata.resolutions[0]}p` : 'Auto',
|
||||
label: `Vidlink ${isDash ? 'DASH' : 'HLS'}`,
|
||||
name: `Vidlink ${isDash ? 'DASH' : 'HLS'}`,
|
||||
type: isDash ? 'dash' : 'hls',
|
||||
headers: stream.playlistHeaders || {},
|
||||
server: 'Vidlink',
|
||||
});
|
||||
}
|
||||
|
||||
if (stream.qualities && typeof stream.qualities === 'object') {
|
||||
const qualityOrder = ['1080', '720', '480', '360', ...Object.keys(stream.qualities)];
|
||||
const seenQualities = new Set();
|
||||
|
||||
for (const q of qualityOrder) {
|
||||
if (seenQualities.has(q)) continue;
|
||||
seenQualities.add(q);
|
||||
const qData = stream.qualities[q];
|
||||
if (!qData?.url || seenUrls.has(qData.url)) continue;
|
||||
seenUrls.add(qData.url);
|
||||
streamList.push({
|
||||
url: qData.url,
|
||||
quality: `${q}p`,
|
||||
label: `Vidlink ${q}p`,
|
||||
name: `Vidlink ${q}p`,
|
||||
type: qData.type || 'mp4',
|
||||
headers: qData.headers || {},
|
||||
server: 'Vidlink',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!streamList.length) return null;
|
||||
|
||||
return {
|
||||
allUrls: streamList,
|
||||
streams: streamList,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
} catch { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSources(args) {
|
||||
const stream = await getStream(args);
|
||||
return stream?.allUrls ? [...new Set(stream.allUrls.map(u => u.server))] : [];
|
||||
return stream?.allUrls ? [...new Set(stream.allUrls.map(u => u.server || 'Vidlink'))] : [];
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { fetchText } from '../utils/helpers.js';
|
||||
|
||||
export async function getStream({ id, s, e }) {
|
||||
const isTv = s != null && e != null;
|
||||
const url = isTv
|
||||
? `https://vidora-3l2w.onrender.com/api/sources?type=tv&id=${id}&season=${s}&episode=${e}`
|
||||
: `https://vidora-3l2w.onrender.com/api/sources?type=movie&id=${id}`;
|
||||
|
||||
const headers = {
|
||||
'Accept': 'text/event-stream',
|
||||
'Referer': 'https://vidora-3l2w.onrender.com/',
|
||||
'Origin': 'https://vidora-3l2w.onrender.com',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
|
||||
};
|
||||
|
||||
const raw = await fetchText(url, { headers }).catch(() => null);
|
||||
if (!raw) return null;
|
||||
|
||||
const lines = raw.split('\n');
|
||||
let doneSources = null;
|
||||
const streamItems = [];
|
||||
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) continue;
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(trimmed);
|
||||
if (parsed.event === 'source' && parsed.source?.url) {
|
||||
streamItems.push(parsed.source);
|
||||
} else if (parsed.event === 'done' && Array.isArray(parsed.sources)) {
|
||||
doneSources = parsed.sources;
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
const targetList = (doneSources && doneSources.length > 0) ? doneSources : streamItems;
|
||||
if (!targetList.length) return null;
|
||||
|
||||
const allUrls = [];
|
||||
|
||||
for (const src of targetList) {
|
||||
if (!src.url || !src.url.startsWith('http')) continue;
|
||||
|
||||
allUrls.push({
|
||||
url: src.url,
|
||||
server: `Vidora - ${src.label || src.server || src.providerGroup || 'Server'} (${src.quality || 'Auto'})`,
|
||||
headers: src.headers || {
|
||||
Referer: 'https://vidora-3l2w.onrender.com/',
|
||||
Origin: 'https://vidora-3l2w.onrender.com'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!allUrls.length) return null;
|
||||
|
||||
return {
|
||||
url: allUrls[0].url,
|
||||
headers: allUrls[0].headers,
|
||||
allUrls
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user