@vyla-entertainment/sdk 1.9.0 → 1.11.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/.github/workflows/publish.yml +38 -38
- package/.gitlab-ci.yml +16 -0
- package/README.md +9 -13
- package/package.json +33 -32
- package/src/config.js +140 -116
- package/src/health.js +2 -2
- package/src/sdk.d.ts +122 -122
- package/src/sdk.js +7 -4
- package/src/sources/anineko.js +3 -1
- package/src/sources/bcine.js +202 -0
- package/src/sources/cinejoy.js +194 -209
- package/src/sources/cinesrc.js +212 -0
- package/src/sources/cinesu.js +147 -93
- package/src/sources/flaxmovies.js +113 -21
- package/src/sources/frame.js +88 -0
- package/src/sources/fsonic.js +3 -1
- package/src/sources/fsonline.js +3 -1
- package/src/sources/lmscript.js +42 -42
- package/src/sources/lookmovie.js +3 -1
- package/src/sources/luna.js +125 -0
- package/src/sources/mapple.js +40 -4
- package/src/sources/megasource.js +47 -0
- package/src/sources/meowtv.js +0 -1
- package/src/sources/nova.js +46 -0
- package/src/sources/peestream.js +122 -0
- package/src/sources/pengu.js +8 -3
- package/src/sources/pstream.js +68 -0
- package/src/sources/rivestream.js +179 -0
- package/src/sources/videasy.js +3 -1
- package/src/sources/vidgod.js +147 -0
- package/src/sources/vidnest.js +3 -1
- package/src/sources/vidvault.js +113 -113
- package/src/sources/vidzee.js +154 -199
- package/src/sources/zxcstream.js +141 -0
- package/src/subtitles.js +18 -0
- package/src/utils/helpers.js +2 -2
- package/src/sources/1embed.js +0 -115
- package/src/sources/anikoto.js +0 -198
- package/src/sources/anizone.js +0 -109
- package/src/sources/kickassanime.js +0 -107
- package/src/sources/nekowatch.js +0 -57
- package/src/sources/opstream.js +0 -123
- package/src/sources/peachify.js +0 -78
- package/src/sources/reanime.js +0 -324
- package/src/sources/vidrift.js +0 -95
- package/src/sources/vidsync.js +0 -38
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
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];
|
|
4
|
+
const _vParam = `_v=${(_sInit[15] ^ 0x5a)}${(_sInit[16] ^ 0x5a)}${(_sInit[17] ^ 0x5a)}${(_sInit[18] ^ 0x5a)}`;
|
|
5
|
+
|
|
6
|
+
const nD = '4860ac8bfddb';
|
|
7
|
+
const aD = '224eff10e662e9635c9f671cf46351dcd69af42b1edd56f5e5fa21751f44b9c8';
|
|
8
|
+
const Ls = [17, 91, 203, 44, 8, 177, 62, 239, 119, 3, 154, 81, 28, 210, 101, 7];
|
|
9
|
+
const wa = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
10
|
+
|
|
11
|
+
const SERVERS = [
|
|
12
|
+
{ id: 'NIGHT', endpoint: '/server/night' },
|
|
13
|
+
{ id: 'EMP', endpoint: '/server/emp' },
|
|
14
|
+
{ id: 'MAIN', endpoint: '/server/vidsrc' }
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
let cachedToken = null;
|
|
18
|
+
let tokenExpiry = 0;
|
|
19
|
+
|
|
20
|
+
function ab(e) {
|
|
21
|
+
let t = e >>> 0;
|
|
22
|
+
t ^= t >>> 16;
|
|
23
|
+
t = Math.imul(t, 2146121005) >>> 0;
|
|
24
|
+
t ^= t >>> 15;
|
|
25
|
+
t = Math.imul(t, 2221713035) >>> 0;
|
|
26
|
+
return (t ^ (t >>> 16)) >>> 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function sD(e) {
|
|
30
|
+
const t = new TextEncoder().encode(aD);
|
|
31
|
+
const r = Math.max(32, Math.min(128, e + 17));
|
|
32
|
+
const n = new Uint8Array(r);
|
|
33
|
+
let a = 2166136261;
|
|
34
|
+
for (let s = 0; s < r; s += 1) {
|
|
35
|
+
a ^= t[s % t.length] ?? s;
|
|
36
|
+
a = ab((a + Ls[s % Ls.length] + ((2654435761 * s) >>> 0)) >>> 0);
|
|
37
|
+
n[s] = a & 255;
|
|
38
|
+
}
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function iD(e) {
|
|
43
|
+
let t = '';
|
|
44
|
+
for (let r = 0; r < e.length; r += 3) {
|
|
45
|
+
const n = e[r];
|
|
46
|
+
const a = e[r + 1];
|
|
47
|
+
const s = e[r + 2];
|
|
48
|
+
t += wa[n >>> 2];
|
|
49
|
+
t += wa[((3 & n) << 4) | ((a ?? 0) >>> 4)];
|
|
50
|
+
if (a === undefined) break;
|
|
51
|
+
t += wa[((15 & a) << 2) | ((s ?? 0) >>> 6)];
|
|
52
|
+
if (s === undefined) break;
|
|
53
|
+
t += wa[63 & s];
|
|
54
|
+
}
|
|
55
|
+
return t;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function generateCinesrcDirectHlsUrl(id, s, e) {
|
|
59
|
+
const isTv = s != null && e != null;
|
|
60
|
+
const tmdbId = Math.floor(Number(id));
|
|
61
|
+
const season = isTv ? Math.floor(Number(s || 1)) : 0;
|
|
62
|
+
const episode = isTv ? Math.floor(Number(e || 1)) : 0;
|
|
63
|
+
|
|
64
|
+
const str = `${nD}:${isTv ? 's' : 'm'}:${tmdbId}:${season}:${episode}`;
|
|
65
|
+
const a = new TextEncoder().encode(str);
|
|
66
|
+
const sArr = sD(a.length);
|
|
67
|
+
const i = new Uint8Array(a.length + 2);
|
|
68
|
+
i[0] = a.length & 255;
|
|
69
|
+
i[1] = (a.length >>> 8) & 255;
|
|
70
|
+
let o = (2654435769 ^ a.length) >>> 0;
|
|
71
|
+
for (let l = 0; l < a.length; l += 1) {
|
|
72
|
+
o = ab((o + sArr[l % sArr.length] + Ls[l % Ls.length] + l) >>> 0);
|
|
73
|
+
i[l + 2] = (a[l] ^ (255 & o)) ^ sArr[(7 * l + 3) % sArr.length];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return `https://glendale-plumbing.com/c/v1/${iD(i)}/master.m3u8`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function fetchBright67Subtitles(id, season, episode) {
|
|
80
|
+
let url = `https://subs.bright67.online/search?id=${id}`;
|
|
81
|
+
if (season != null && episode != null) {
|
|
82
|
+
url += `&season=${season}&episode=${episode}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const res = await fetch(url, {
|
|
87
|
+
headers: {
|
|
88
|
+
'User-Agent': USER_AGENT,
|
|
89
|
+
'Referer': 'https://cinesrc.st/'
|
|
90
|
+
},
|
|
91
|
+
signal: AbortSignal.timeout(4000)
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (!res.ok) return [];
|
|
95
|
+
const data = await res.json();
|
|
96
|
+
if (!Array.isArray(data)) return [];
|
|
97
|
+
|
|
98
|
+
return data.slice(0, 15).map(s => ({
|
|
99
|
+
label: s.display || s.languageName || s.language || 'English',
|
|
100
|
+
language: s.language || 'en',
|
|
101
|
+
file: s.url || s.r2Url,
|
|
102
|
+
type: (s.url || s.r2Url || '').endsWith('.vtt') ? 'vtt' : 'srt'
|
|
103
|
+
}));
|
|
104
|
+
} catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function fetchInternalToken() {
|
|
110
|
+
if (cachedToken && Date.now() < tokenExpiry) return cachedToken;
|
|
111
|
+
try {
|
|
112
|
+
const res = await fetch('https://1embed.cc/api/token', {
|
|
113
|
+
headers: {
|
|
114
|
+
'User-Agent': USER_AGENT,
|
|
115
|
+
'Referer': 'https://1embed.cc/',
|
|
116
|
+
'Accept': 'application/json, text/plain, */*'
|
|
117
|
+
},
|
|
118
|
+
signal: AbortSignal.timeout(4000)
|
|
119
|
+
});
|
|
120
|
+
if (res.ok) {
|
|
121
|
+
const data = await res.json();
|
|
122
|
+
if (data?.token) {
|
|
123
|
+
cachedToken = data.token;
|
|
124
|
+
tokenExpiry = Date.now() + 1800 * 1000;
|
|
125
|
+
return cachedToken;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch { }
|
|
129
|
+
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function getStream(args) {
|
|
134
|
+
const { id, s, e, clientIP } = args;
|
|
135
|
+
const isTv = s != null && e != null;
|
|
136
|
+
const isMovie = !isTv;
|
|
137
|
+
const allUrls = [];
|
|
138
|
+
|
|
139
|
+
const [subtitles, directHlsUrl] = await Promise.all([
|
|
140
|
+
fetchBright67Subtitles(id, isMovie ? undefined : s, isMovie ? undefined : e),
|
|
141
|
+
Promise.resolve(generateCinesrcDirectHlsUrl(id, s, e))
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
const masterUrlWithMark = `${directHlsUrl}?${_vParam}`;
|
|
145
|
+
|
|
146
|
+
allUrls.push({
|
|
147
|
+
url: masterUrlWithMark,
|
|
148
|
+
server: 'CineSrc (Direct Master)',
|
|
149
|
+
quality: 'Auto',
|
|
150
|
+
type: 'hls',
|
|
151
|
+
headers: {
|
|
152
|
+
'User-Agent': USER_AGENT,
|
|
153
|
+
'Referer': 'https://cinesrc.st/',
|
|
154
|
+
'Origin': 'https://cinesrc.st',
|
|
155
|
+
...(clientIP && { 'X-Forwarded-For': clientIP })
|
|
156
|
+
},
|
|
157
|
+
subtitles: subtitles.length ? subtitles : undefined
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const token = await fetchInternalToken();
|
|
161
|
+
|
|
162
|
+
await Promise.allSettled(
|
|
163
|
+
SERVERS.map(async (server) => {
|
|
164
|
+
const query = isTv
|
|
165
|
+
? `id=${id}?type=tv&s=${s || 1}&e=${e || 1}`
|
|
166
|
+
: `id=${id}?type=movie`;
|
|
167
|
+
|
|
168
|
+
const stParam = token ? `&_st=${token}` : '';
|
|
169
|
+
const targetUrl = `https://1embed.cc${server.endpoint}/${query}${stParam}`;
|
|
170
|
+
|
|
171
|
+
const headers = {
|
|
172
|
+
'User-Agent': USER_AGENT,
|
|
173
|
+
'Referer': 'https://cinesrc.st/',
|
|
174
|
+
'Accept': 'application/json, text/plain, */*',
|
|
175
|
+
...(token && { 'X-Stream-Token': token }),
|
|
176
|
+
...(clientIP && { 'X-Forwarded-For': clientIP })
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const res = await fetch(targetUrl, { headers, signal: AbortSignal.timeout(5000) }).catch(() => null);
|
|
180
|
+
|
|
181
|
+
if (res && res.ok) {
|
|
182
|
+
try {
|
|
183
|
+
const data = await res.json();
|
|
184
|
+
if (data && data.success !== false) {
|
|
185
|
+
const streamUrl = data.streams?.proxy_m3u8 || data.streams?.raw_m3u8 || data.streams?.m3u8 || data.streamUrl;
|
|
186
|
+
if (streamUrl && typeof streamUrl === 'string') {
|
|
187
|
+
const urlWithMark = streamUrl.includes('?') ? `${streamUrl}&${_vParam}` : `${streamUrl}?${_vParam}`;
|
|
188
|
+
allUrls.push({
|
|
189
|
+
url: urlWithMark,
|
|
190
|
+
server: `CineSrc (${data.selectedSource || data.provider || server.id})`,
|
|
191
|
+
quality: 'Auto',
|
|
192
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
193
|
+
headers: {
|
|
194
|
+
'User-Agent': USER_AGENT,
|
|
195
|
+
'Referer': 'https://cinesrc.st/',
|
|
196
|
+
'Origin': 'https://cinesrc.st'
|
|
197
|
+
},
|
|
198
|
+
subtitles: subtitles.length ? subtitles : undefined
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
} catch { }
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
return allUrls.length ? { allUrls } : null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export async function getSources() {
|
|
211
|
+
return ['CineSrc (Direct Master)', 'CineSrc (NIGHT)', 'CineSrc (EMP)', 'CineSrc (MAIN)'];
|
|
212
|
+
}
|
package/src/sources/cinesu.js
CHANGED
|
@@ -1,94 +1,148 @@
|
|
|
1
|
-
import { USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export async function
|
|
93
|
-
|
|
1
|
+
import { USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_DOMAIN = 'https://glendale-plumbing.com';
|
|
4
|
+
const REFERER = 'https://cine.su/';
|
|
5
|
+
|
|
6
|
+
const nD = '4860ac8bfddb';
|
|
7
|
+
const aD = '224eff10e662e9635c9f671cf46351dcd69af42b1edd56f5e5fa21751f44b9c8';
|
|
8
|
+
const Ls = [17, 91, 203, 44, 8, 177, 62, 239, 119, 3, 154, 81, 28, 210, 101, 7];
|
|
9
|
+
const wa = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
10
|
+
|
|
11
|
+
function ab(e) {
|
|
12
|
+
let t = e >>> 0;
|
|
13
|
+
t ^= t >>> 16;
|
|
14
|
+
t = Math.imul(t, 2146121005) >>> 0;
|
|
15
|
+
t ^= t >>> 15;
|
|
16
|
+
t = Math.imul(t, 2221713035) >>> 0;
|
|
17
|
+
return (t ^ (t >>> 16)) >>> 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function sD(e) {
|
|
21
|
+
const t = new TextEncoder().encode(aD);
|
|
22
|
+
const r = Math.max(32, Math.min(128, e + 17));
|
|
23
|
+
const n = new Uint8Array(r);
|
|
24
|
+
let a = 2166136261;
|
|
25
|
+
for (let s = 0; s < r; s += 1) {
|
|
26
|
+
a ^= t[s % t.length] ?? s;
|
|
27
|
+
a = ab((a + Ls[s % Ls.length] + ((2654435761 * s) >>> 0)) >>> 0);
|
|
28
|
+
n[s] = a & 255;
|
|
29
|
+
}
|
|
30
|
+
return n;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function iD(e) {
|
|
34
|
+
let t = '';
|
|
35
|
+
for (let r = 0; r < e.length; r += 3) {
|
|
36
|
+
const n = e[r];
|
|
37
|
+
const a = e[r + 1];
|
|
38
|
+
const s = e[r + 2];
|
|
39
|
+
t += wa[n >>> 2];
|
|
40
|
+
t += wa[((3 & n) << 4) | ((a ?? 0) >>> 4)];
|
|
41
|
+
if (a === undefined) break;
|
|
42
|
+
t += wa[((15 & a) << 2) | ((s ?? 0) >>> 6)];
|
|
43
|
+
if (s === undefined) break;
|
|
44
|
+
t += wa[63 & s];
|
|
45
|
+
}
|
|
46
|
+
return t;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function generateMasterUrl(id, s, e) {
|
|
50
|
+
const isTv = s != null && e != null;
|
|
51
|
+
const tmdbId = Math.floor(Number(id));
|
|
52
|
+
const season = isTv ? Math.floor(Number(s || 1)) : 0;
|
|
53
|
+
const episode = isTv ? Math.floor(Number(e || 1)) : 0;
|
|
54
|
+
|
|
55
|
+
const str = `${nD}:${isTv ? 's' : 'm'}:${tmdbId}:${season}:${episode}`;
|
|
56
|
+
const a = new TextEncoder().encode(str);
|
|
57
|
+
const sArr = sD(a.length);
|
|
58
|
+
const i = new Uint8Array(a.length + 2);
|
|
59
|
+
i[0] = a.length & 255;
|
|
60
|
+
i[1] = (a.length >>> 8) & 255;
|
|
61
|
+
let o = (2654435769 ^ a.length) >>> 0;
|
|
62
|
+
for (let l = 0; l < a.length; l += 1) {
|
|
63
|
+
o = ab((o + sArr[l % sArr.length] + Ls[l % Ls.length] + l) >>> 0);
|
|
64
|
+
i[l + 2] = (a[l] ^ (255 & o)) ^ sArr[(7 * l + 3) % sArr.length];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return `${BASE_DOMAIN}/c/v1/${iD(i)}/master.m3u8`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function parsePlaylist(m3u8Text) {
|
|
71
|
+
const qualities = [];
|
|
72
|
+
const subtitles = [];
|
|
73
|
+
|
|
74
|
+
const subRegex = /#EXT-X-MEDIA:TYPE=SUBTITLES,[^\n]*NAME="([^"]*)"[^\n]*LANGUAGE="([^"]*)"[^\n]*URI="([^"]*)"/g;
|
|
75
|
+
let match;
|
|
76
|
+
while ((match = subRegex.exec(m3u8Text)) !== null) {
|
|
77
|
+
let uri = match[3];
|
|
78
|
+
if (uri.startsWith('/')) uri = `${BASE_DOMAIN}${uri}`;
|
|
79
|
+
subtitles.push({ label: match[1], language: match[2], file: uri, type: 'vtt' });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const streamRegex = /#EXT-X-STREAM-INF:[^\n]*RESOLUTION=\d+x(\d+)[^\n]*\r?\n([^\n#][^\n]*)/g;
|
|
83
|
+
while ((match = streamRegex.exec(m3u8Text)) !== null) {
|
|
84
|
+
let streamPath = match[2].trim();
|
|
85
|
+
if (streamPath.startsWith('/')) streamPath = `${BASE_DOMAIN}${streamPath}`;
|
|
86
|
+
qualities.push({ quality: `${match[1]}p`, url: streamPath });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { qualities, subtitles };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function getStream(args) {
|
|
93
|
+
const { id, s, e, clientIP } = args;
|
|
94
|
+
const rawMasterUrl = generateMasterUrl(id, s, e);
|
|
95
|
+
|
|
96
|
+
const headers = {
|
|
97
|
+
'User-Agent': USER_AGENT,
|
|
98
|
+
'Referer': REFERER,
|
|
99
|
+
'Origin': 'https://cine.su',
|
|
100
|
+
...(clientIP && { 'X-Forwarded-For': clientIP })
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const res = await fetch(rawMasterUrl, {
|
|
105
|
+
headers,
|
|
106
|
+
signal: AbortSignal.timeout(5000)
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (res.ok) {
|
|
110
|
+
const text = await res.text();
|
|
111
|
+
const { qualities, subtitles } = parsePlaylist(text);
|
|
112
|
+
|
|
113
|
+
if (qualities.length) {
|
|
114
|
+
const allUrls = [{
|
|
115
|
+
url: rawMasterUrl,
|
|
116
|
+
server: 'CineSu (Auto)',
|
|
117
|
+
quality: 'Auto',
|
|
118
|
+
type: 'hls',
|
|
119
|
+
headers,
|
|
120
|
+
subtitles: subtitles.length ? subtitles : undefined
|
|
121
|
+
}];
|
|
122
|
+
|
|
123
|
+
for (const q of qualities) {
|
|
124
|
+
allUrls.push({
|
|
125
|
+
url: q.url,
|
|
126
|
+
server: `CineSu (${q.quality})`,
|
|
127
|
+
quality: q.quality,
|
|
128
|
+
type: 'hls',
|
|
129
|
+
headers,
|
|
130
|
+
subtitles: subtitles.length ? subtitles : undefined
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return { allUrls };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch { }
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
allUrls: [{
|
|
141
|
+
url: rawMasterUrl,
|
|
142
|
+
server: 'CineSu',
|
|
143
|
+
quality: 'Auto',
|
|
144
|
+
type: 'hls',
|
|
145
|
+
headers
|
|
146
|
+
}]
|
|
147
|
+
};
|
|
94
148
|
}
|
|
@@ -1,26 +1,118 @@
|
|
|
1
|
-
import { fetchJson } from '../utils/helpers.js';
|
|
1
|
+
import { USER_AGENT, fetchJson } from '../utils/helpers.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const BASE_URL = 'https://flaxmovies.xyz';
|
|
4
|
+
|
|
5
|
+
async function getWorkerUrls(embedUrl) {
|
|
6
|
+
const foundUrls = [];
|
|
4
7
|
try {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
const res = await fetch(embedUrl, {
|
|
9
|
+
headers: {
|
|
10
|
+
'User-Agent': USER_AGENT,
|
|
11
|
+
'Referer': `${BASE_URL}/`,
|
|
12
|
+
'Origin': BASE_URL
|
|
13
|
+
},
|
|
14
|
+
signal: AbortSignal.timeout(8000)
|
|
15
|
+
});
|
|
16
|
+
if (res.ok) {
|
|
17
|
+
const html = await res.text();
|
|
18
|
+
const directMatch = html.match(/WORKER_URL\s*[:=]\s*["'](https?:\/\/[^"']+)["']/i);
|
|
19
|
+
if (directMatch && directMatch[1]) {
|
|
20
|
+
foundUrls.push(directMatch[1].replace(/\/+$/, ''));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const scriptMatches = [...html.matchAll(/<script[^>]+src=["']([^"']+)["']/gi)];
|
|
24
|
+
for (const sm of scriptMatches) {
|
|
25
|
+
let scriptUrl = sm[1];
|
|
26
|
+
if (scriptUrl.startsWith('//')) scriptUrl = `https:${scriptUrl}`;
|
|
27
|
+
else if (scriptUrl.startsWith('/')) scriptUrl = `${BASE_URL}${scriptUrl}`;
|
|
28
|
+
else if (!scriptUrl.startsWith('http')) scriptUrl = `${BASE_URL}/${scriptUrl}`;
|
|
29
|
+
|
|
30
|
+
if (scriptUrl.includes('jsdelivr') || scriptUrl.includes('google') || scriptUrl.includes('cloudflare')) continue;
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const sRes = await fetch(scriptUrl, {
|
|
34
|
+
headers: { 'User-Agent': USER_AGENT, 'Referer': embedUrl },
|
|
35
|
+
signal: AbortSignal.timeout(6000)
|
|
36
|
+
});
|
|
37
|
+
if (sRes.ok) {
|
|
38
|
+
const sCode = await sRes.text();
|
|
39
|
+
const m = sCode.match(/WORKER_URL\s*[:=]\s*["'](https?:\/\/[^"']+)["']/i);
|
|
40
|
+
if (m && m[1]) {
|
|
41
|
+
const wUrl = m[1].replace(/\/+$/, '');
|
|
42
|
+
if (!foundUrls.includes(wUrl)) foundUrls.push(wUrl);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch { }
|
|
46
|
+
}
|
|
21
47
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
48
|
+
} catch { }
|
|
49
|
+
|
|
50
|
+
const defaults = ['https://freakyniki.elaxo.lol', 'https://vidlove.nabilekson.workers.dev'];
|
|
51
|
+
for (const d of defaults) {
|
|
52
|
+
if (!foundUrls.includes(d)) foundUrls.push(d);
|
|
53
|
+
}
|
|
54
|
+
return foundUrls;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function getStream(args) {
|
|
58
|
+
const { id, s, e, server } = args;
|
|
59
|
+
const isTv = s != null && e != null;
|
|
60
|
+
const embedUrl = isTv
|
|
61
|
+
? `${BASE_URL}/embed/tv/${id}/${s}/${e}`
|
|
62
|
+
: `${BASE_URL}/embed/movie/${id}`;
|
|
63
|
+
|
|
64
|
+
const workerUrls = await getWorkerUrls(embedUrl);
|
|
65
|
+
const query = isTv
|
|
66
|
+
? `tmdb_id=${id}&tmdbId=${id}&season=${s}&episode=${e}`
|
|
67
|
+
: `tmdb_id=${id}&tmdbId=${id}`;
|
|
68
|
+
|
|
69
|
+
for (const worker of workerUrls) {
|
|
70
|
+
try {
|
|
71
|
+
const url = `${worker}/?${query}`;
|
|
72
|
+
const data = await fetchJson(url, {
|
|
73
|
+
headers: {
|
|
74
|
+
'User-Agent': USER_AGENT,
|
|
75
|
+
'Referer': `${BASE_URL}/`,
|
|
76
|
+
'Origin': BASE_URL,
|
|
77
|
+
'Accept': 'application/json, text/plain, */*'
|
|
78
|
+
},
|
|
79
|
+
signal: AbortSignal.timeout(12000)
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (data && Array.isArray(data.streams) && data.streams.length > 0) {
|
|
83
|
+
let allUrls = data.streams
|
|
84
|
+
.filter(st => st && typeof st.url === 'string')
|
|
85
|
+
.map(st => {
|
|
86
|
+
const isHls = (st.format || '').toLowerCase().includes('hls') || st.url.includes('.m3u8');
|
|
87
|
+
return {
|
|
88
|
+
url: st.url,
|
|
89
|
+
server: `FlaxMovies - ${st.provider || 'Default'}`,
|
|
90
|
+
quality: st.resolution || 'Auto',
|
|
91
|
+
type: isHls ? 'hls' : 'mp4',
|
|
92
|
+
headers: {
|
|
93
|
+
'User-Agent': USER_AGENT,
|
|
94
|
+
'Referer': `${BASE_URL}/`,
|
|
95
|
+
'Origin': BASE_URL
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
if (server && server !== 'all') {
|
|
101
|
+
const clean = server.toLowerCase().replace('flaxmovies - ', '');
|
|
102
|
+
const filtered = allUrls.filter(u => u.server.toLowerCase().includes(clean));
|
|
103
|
+
if (filtered.length) allUrls = filtered;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (allUrls.length) {
|
|
107
|
+
return { allUrls };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} catch { }
|
|
25
111
|
}
|
|
112
|
+
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function getSources() {
|
|
117
|
+
return ['FlaxMovies - Airflix', 'FlaxMovies - Xpass-VIP 1'];
|
|
26
118
|
}
|