@vyla-entertainment/sdk 1.21.0 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/config.js +145 -0
- package/src/health.js +60 -20
- package/src/sources/4movies.js +77 -0
- package/src/sources/aether.js +99 -0
- package/src/sources/braflix.js +80 -0
- package/src/sources/castle.js +415 -0
- package/src/sources/framextv.js +126 -0
- package/src/sources/meowtv.js +140 -0
- package/src/sources/vidora.js +94 -0
- package/src/sources/zenox.js +108 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const BASE_URL = 'https://vidoraplayer.duckdns.org';
|
|
2
|
+
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';
|
|
3
|
+
|
|
4
|
+
const HEADERS = {
|
|
5
|
+
'User-Agent': UA,
|
|
6
|
+
Referer: `${BASE_URL}/`,
|
|
7
|
+
Origin: BASE_URL,
|
|
8
|
+
Accept: 'application/x-ndjson, text/plain, */*',
|
|
9
|
+
'Accept-Language': 'en-US,en;q=0.9',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function parseNdjson(text) {
|
|
13
|
+
if (!text) return [];
|
|
14
|
+
const normalized = text.replace(/\}\s*\{/g, '}\n{');
|
|
15
|
+
const lines = normalized.split('\n');
|
|
16
|
+
const items = [];
|
|
17
|
+
for (const raw of lines) {
|
|
18
|
+
const line = raw.trim();
|
|
19
|
+
if (!line) continue;
|
|
20
|
+
try {
|
|
21
|
+
items.push(JSON.parse(line));
|
|
22
|
+
} catch { }
|
|
23
|
+
}
|
|
24
|
+
return items;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function getStream(args) {
|
|
28
|
+
const { id, s, e } = args || {};
|
|
29
|
+
const isTv = s != null && e != null;
|
|
30
|
+
|
|
31
|
+
const query = isTv
|
|
32
|
+
? `type=tv&id=${id}&season=${s}&episode=${e}`
|
|
33
|
+
: `type=movie&id=${id}`;
|
|
34
|
+
|
|
35
|
+
const urls = [
|
|
36
|
+
`${BASE_URL}/api/sources?${query}`,
|
|
37
|
+
`${BASE_URL}/api/sources?${query}&gen=2`,
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const responses = await Promise.all(
|
|
41
|
+
urls.map(url =>
|
|
42
|
+
fetch(url, { headers: HEADERS })
|
|
43
|
+
.then(r => (r.ok ? r.text() : ''))
|
|
44
|
+
.catch(() => '')
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const allUrls = [];
|
|
49
|
+
const seen = new Set();
|
|
50
|
+
|
|
51
|
+
for (const text of responses) {
|
|
52
|
+
const events = parseNdjson(text);
|
|
53
|
+
for (const item of events) {
|
|
54
|
+
const list = [];
|
|
55
|
+
if (item?.event === 'source' && item?.source) {
|
|
56
|
+
list.push(item.source);
|
|
57
|
+
} else if (item?.event === 'done' && Array.isArray(item?.sources)) {
|
|
58
|
+
list.push(...item.sources);
|
|
59
|
+
} else if (item?.url) {
|
|
60
|
+
list.push(item);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (const src of list) {
|
|
64
|
+
if (!src?.url) continue;
|
|
65
|
+
const fullUrl = src.url.startsWith('http')
|
|
66
|
+
? src.url
|
|
67
|
+
: `${BASE_URL}${src.url.startsWith('/') ? '' : '/'}${src.url}`;
|
|
68
|
+
|
|
69
|
+
if (!seen.has(fullUrl)) {
|
|
70
|
+
seen.add(fullUrl);
|
|
71
|
+
allUrls.push({
|
|
72
|
+
url: fullUrl,
|
|
73
|
+
server: `Vidora - ${src.label || src.server || src.providerGroup || 'Default'}`,
|
|
74
|
+
quality: src.quality || 'Auto',
|
|
75
|
+
type: src.type || (fullUrl.includes('.m3u8') ? 'hls' : 'mp4'),
|
|
76
|
+
headers: {
|
|
77
|
+
Referer: `${BASE_URL}/`,
|
|
78
|
+
Origin: BASE_URL,
|
|
79
|
+
'User-Agent': UA,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!allUrls.length) return null;
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
url: allUrls[0].url,
|
|
91
|
+
headers: allUrls[0].headers,
|
|
92
|
+
allUrls,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const BASE_URL = 'https://zenox.lol';
|
|
2
|
+
const API_URL = `${BASE_URL}/api/v1/playback/session`;
|
|
3
|
+
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';
|
|
4
|
+
|
|
5
|
+
const HEADERS = {
|
|
6
|
+
'Content-Type': 'application/json',
|
|
7
|
+
Origin: BASE_URL,
|
|
8
|
+
Referer: `${BASE_URL}/`,
|
|
9
|
+
'User-Agent': UA,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const PLAYBACK_HEADERS = {
|
|
13
|
+
Origin: BASE_URL,
|
|
14
|
+
Referer: `${BASE_URL}/`,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
async function fetchServerStream(payload, srv) {
|
|
18
|
+
try {
|
|
19
|
+
const res = await fetch(API_URL, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: HEADERS,
|
|
22
|
+
body: JSON.stringify({
|
|
23
|
+
...payload,
|
|
24
|
+
serverIndex: srv.index,
|
|
25
|
+
serverName: srv.name,
|
|
26
|
+
}),
|
|
27
|
+
signal: AbortSignal.timeout(6000),
|
|
28
|
+
});
|
|
29
|
+
if (!res.ok) return null;
|
|
30
|
+
const data = await res.json();
|
|
31
|
+
if (
|
|
32
|
+
!data?.success ||
|
|
33
|
+
!data?.streamUrl ||
|
|
34
|
+
data.streamUrl.includes('/primary/') ||
|
|
35
|
+
data.serverName?.toLowerCase() === 'primary'
|
|
36
|
+
) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const streamUrl = data.streamUrl.startsWith('http')
|
|
41
|
+
? data.streamUrl
|
|
42
|
+
: `${BASE_URL}${data.streamUrl}`;
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
url: streamUrl,
|
|
46
|
+
server: `Zenox - ${data.serverName || srv.name}`,
|
|
47
|
+
quality: 'Auto',
|
|
48
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : (streamUrl.includes('.mpd') ? 'dash' : 'mp4'),
|
|
49
|
+
headers: PLAYBACK_HEADERS,
|
|
50
|
+
};
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function getStream(args) {
|
|
57
|
+
const { id, s, e, title, year, imdbId } = args || {};
|
|
58
|
+
const idNum = parseInt(id, 10);
|
|
59
|
+
if (!idNum) return null;
|
|
60
|
+
|
|
61
|
+
const isTv = s != null && e != null;
|
|
62
|
+
const payload = {
|
|
63
|
+
mediaId: idNum,
|
|
64
|
+
mediaType: isTv ? 'tv' : 'movie',
|
|
65
|
+
season: isTv ? (parseInt(s, 10) || 1) : 1,
|
|
66
|
+
episode: isTv ? (parseInt(e, 10) || 1) : 1,
|
|
67
|
+
title: title || '',
|
|
68
|
+
year: String(year || ''),
|
|
69
|
+
imdbId: imdbId || '',
|
|
70
|
+
autoUseCommunity: false,
|
|
71
|
+
isManualSwitch: true,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const activeServers = [
|
|
75
|
+
{ name: 'Vbot', index: 1 },
|
|
76
|
+
{ name: 'Temporary', index: 1 },
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
const results = await Promise.allSettled(
|
|
80
|
+
activeServers.map(srv => fetchServerStream(payload, srv))
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const allUrls = [];
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
|
|
86
|
+
for (const r of results) {
|
|
87
|
+
if (r.status === 'fulfilled' && r.value?.url && !seen.has(r.value.url)) {
|
|
88
|
+
seen.add(r.value.url);
|
|
89
|
+
allUrls.push(r.value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!allUrls.length) {
|
|
94
|
+
const delta = await fetchServerStream(payload, { name: 'Delta', index: 0 });
|
|
95
|
+
if (delta?.url && !seen.has(delta.url)) {
|
|
96
|
+
seen.add(delta.url);
|
|
97
|
+
allUrls.push(delta);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!allUrls.length) return null;
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
url: allUrls[0].url,
|
|
105
|
+
headers: allUrls[0].headers,
|
|
106
|
+
allUrls,
|
|
107
|
+
};
|
|
108
|
+
}
|