@vyla-entertainment/sdk 1.11.0 → 1.13.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/package.json +2 -2
- package/src/config.js +80 -245
- package/src/downloads/downloads.js +51 -10
- package/src/sdk.d.ts +0 -1
- package/src/sdk.js +1 -1
- package/src/sources/111477.js +101 -0
- package/src/sources/dulo.js +150 -0
- package/src/sources/movienight.js +117 -0
- package/src/sources/movy.js +282 -0
- package/src/sources/purstream.js +2 -2
- package/src/sources/streamaggregator.js +129 -0
- package/src/sources/vidvault.js +131 -57
- package/src/sources/xdownloader.js +129 -0
- package/src/subtitles.js +35 -40
- package/src/downloads/sources/trendimovies.js +0 -63
- package/src/sources/anipm.js +0 -70
- package/src/sources/cinejoy.js +0 -195
- package/src/sources/cinesrc.js +0 -212
- package/src/sources/cinesu.js +0 -148
- package/src/sources/frame.js +0 -88
- package/src/sources/fsharetv.js +0 -44
- package/src/sources/fsonic.js +0 -49
- package/src/sources/hexa.js +0 -82
- package/src/sources/luna.js +0 -125
- package/src/sources/mapple.js +0 -151
- package/src/sources/megasource.js +0 -47
- package/src/sources/meowtv.js +0 -103
- package/src/sources/nova.js +0 -46
- package/src/sources/peestream.js +0 -122
- package/src/sources/vidcore.js +0 -43
- package/src/sources/videasy.js +0 -94
- package/src/sources/vidfast.js +0 -53
- package/src/sources/xpass.js +0 -40
- package/src/sources/zxcstream.js +0 -141
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Currently active sources reported on
|
|
1
|
+
// Currently active sources reported on 6:18:22 PM PST 9/13/2026
|
|
2
2
|
|
|
3
3
|
// None Anime Tested: 936075
|
|
4
4
|
// Anime Tested: 37854
|
|
@@ -25,6 +25,25 @@ export const SOURCES = [
|
|
|
25
25
|
},],
|
|
26
26
|
},
|
|
27
27
|
|
|
28
|
+
{
|
|
29
|
+
key: '111477',
|
|
30
|
+
label: '111477',
|
|
31
|
+
sourceFile: '111477',
|
|
32
|
+
proxyParam: 'a11',
|
|
33
|
+
timeout: 25000,
|
|
34
|
+
jitter: 500,
|
|
35
|
+
retries: 2,
|
|
36
|
+
multiUrl: true,
|
|
37
|
+
skipProxy: true,
|
|
38
|
+
cdnHeaders: [{
|
|
39
|
+
pattern: /111477\.xyz/i,
|
|
40
|
+
headers: {
|
|
41
|
+
Referer: 'https://st.111477.xyz/',
|
|
42
|
+
Origin: 'https://st.111477.xyz',
|
|
43
|
+
},
|
|
44
|
+
}],
|
|
45
|
+
},
|
|
46
|
+
|
|
28
47
|
{
|
|
29
48
|
key: 'anihq-sub',
|
|
30
49
|
label: 'AniHQ (Sub)',
|
|
@@ -69,40 +88,6 @@ export const SOURCES = [
|
|
|
69
88
|
retries: 2
|
|
70
89
|
},
|
|
71
90
|
|
|
72
|
-
{
|
|
73
|
-
key: 'anipm-sub',
|
|
74
|
-
sourceFile: 'anipm',
|
|
75
|
-
label: 'AniPM (Sub)',
|
|
76
|
-
proxyParam: 'apsub',
|
|
77
|
-
timeout: 25000,
|
|
78
|
-
jitter: 500,
|
|
79
|
-
retries: 2,
|
|
80
|
-
skipProxy: true,
|
|
81
|
-
skipVerify: true,
|
|
82
|
-
multiUrl: true,
|
|
83
|
-
verifyHeaders: {
|
|
84
|
-
Referer: 'https://ani.pm/',
|
|
85
|
-
Origin: 'https://ani.pm',
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
key: 'anipm-dub',
|
|
91
|
-
sourceFile: 'anipm',
|
|
92
|
-
label: 'AniPM (Dub)',
|
|
93
|
-
proxyParam: 'apdub',
|
|
94
|
-
timeout: 25000,
|
|
95
|
-
jitter: 500,
|
|
96
|
-
retries: 2,
|
|
97
|
-
skipProxy: true,
|
|
98
|
-
skipVerify: true,
|
|
99
|
-
multiUrl: true,
|
|
100
|
-
verifyHeaders: {
|
|
101
|
-
Referer: 'https://ani.pm/',
|
|
102
|
-
Origin: 'https://ani.pm',
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
|
|
106
91
|
{
|
|
107
92
|
key: 'bcine',
|
|
108
93
|
label: 'Bcine',
|
|
@@ -122,53 +107,20 @@ export const SOURCES = [
|
|
|
122
107
|
},
|
|
123
108
|
|
|
124
109
|
{
|
|
125
|
-
key: '
|
|
126
|
-
label: '
|
|
127
|
-
sourceFile: '
|
|
128
|
-
proxyParam: '
|
|
129
|
-
timeout: 30000,
|
|
130
|
-
jitter: 500,
|
|
131
|
-
retries: 1,
|
|
132
|
-
multiUrl: true,
|
|
133
|
-
skipProxy: true,
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
{
|
|
137
|
-
key: 'cinesrc',
|
|
138
|
-
label: 'CineSrc',
|
|
139
|
-
sourceFile: 'cinesrc',
|
|
140
|
-
proxyParam: 'csr',
|
|
110
|
+
key: 'dulo',
|
|
111
|
+
label: 'Dulo',
|
|
112
|
+
sourceFile: 'dulo',
|
|
113
|
+
proxyParam: 'dl',
|
|
141
114
|
timeout: 25000,
|
|
142
115
|
jitter: 500,
|
|
143
116
|
retries: 2,
|
|
144
117
|
multiUrl: true,
|
|
145
118
|
skipProxy: true,
|
|
146
|
-
skipVerify: true,
|
|
147
119
|
cdnHeaders: [{
|
|
148
|
-
pattern: /
|
|
120
|
+
pattern: /dulo\.mov/i,
|
|
149
121
|
headers: {
|
|
150
|
-
Referer: 'https://
|
|
151
|
-
Origin: 'https://
|
|
152
|
-
},
|
|
153
|
-
}],
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
{
|
|
157
|
-
key: 'cinesu',
|
|
158
|
-
label: 'CineSu',
|
|
159
|
-
sourceFile: 'cinesu',
|
|
160
|
-
proxyParam: 'cs',
|
|
161
|
-
timeout: 25000,
|
|
162
|
-
jitter: 500,
|
|
163
|
-
retries: 2,
|
|
164
|
-
multiUrl: true,
|
|
165
|
-
skipProxy: true,
|
|
166
|
-
skipVerify: true,
|
|
167
|
-
cdnHeaders: [{
|
|
168
|
-
pattern: /glendale-plumbing\.com/i,
|
|
169
|
-
headers: {
|
|
170
|
-
Referer: 'https://cine.su/',
|
|
171
|
-
Origin: 'https://cine.su',
|
|
122
|
+
Referer: 'https://dulo.mov/',
|
|
123
|
+
Origin: 'https://dulo.mov',
|
|
172
124
|
},
|
|
173
125
|
}],
|
|
174
126
|
},
|
|
@@ -192,45 +144,6 @@ export const SOURCES = [
|
|
|
192
144
|
},],
|
|
193
145
|
},
|
|
194
146
|
|
|
195
|
-
{
|
|
196
|
-
key: 'frame',
|
|
197
|
-
label: 'Frame',
|
|
198
|
-
sourceFile: 'frame',
|
|
199
|
-
proxyParam: 'fr',
|
|
200
|
-
timeout: 25000,
|
|
201
|
-
jitter: 500,
|
|
202
|
-
retries: 2,
|
|
203
|
-
multiUrl: true,
|
|
204
|
-
skipProxy: true,
|
|
205
|
-
},
|
|
206
|
-
|
|
207
|
-
{
|
|
208
|
-
key: 'fsharetv',
|
|
209
|
-
label: 'FShareTV',
|
|
210
|
-
sourceFile: 'fsharetv',
|
|
211
|
-
proxyParam: 'fs',
|
|
212
|
-
timeout: 25000,
|
|
213
|
-
jitter: 600,
|
|
214
|
-
retries: 2,
|
|
215
|
-
multiUrl: false,
|
|
216
|
-
verifyHeaders: {
|
|
217
|
-
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8',
|
|
218
|
-
'Accept-Language': 'en-US,en;q=0.9',
|
|
219
|
-
Referer: 'https://fsharetv.cc',
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
|
|
223
|
-
{
|
|
224
|
-
key: 'fsonic',
|
|
225
|
-
label: 'Fsonic',
|
|
226
|
-
sourceFile: 'fsonic',
|
|
227
|
-
proxyParam: 'fn',
|
|
228
|
-
timeout: 35000,
|
|
229
|
-
jitter: 600,
|
|
230
|
-
retries: 1,
|
|
231
|
-
multiUrl: true,
|
|
232
|
-
},
|
|
233
|
-
|
|
234
147
|
{
|
|
235
148
|
key: 'fsonline',
|
|
236
149
|
label: 'FSOnline',
|
|
@@ -243,16 +156,6 @@ export const SOURCES = [
|
|
|
243
156
|
skipProxy: true,
|
|
244
157
|
},
|
|
245
158
|
|
|
246
|
-
{
|
|
247
|
-
key: 'hexa',
|
|
248
|
-
label: 'Hexa',
|
|
249
|
-
sourceFile: 'hexa',
|
|
250
|
-
proxyParam: 'hx',
|
|
251
|
-
timeout: 20000,
|
|
252
|
-
jitter: 500,
|
|
253
|
-
retries: 2,
|
|
254
|
-
},
|
|
255
|
-
|
|
256
159
|
{
|
|
257
160
|
key: 'kisskh',
|
|
258
161
|
label: 'KissKH',
|
|
@@ -289,63 +192,41 @@ export const SOURCES = [
|
|
|
289
192
|
},
|
|
290
193
|
|
|
291
194
|
{
|
|
292
|
-
key: '
|
|
293
|
-
label: '
|
|
294
|
-
sourceFile: '
|
|
295
|
-
proxyParam: '
|
|
296
|
-
subtype: 'sub',
|
|
297
|
-
timeout: 25000,
|
|
298
|
-
jitter: 500,
|
|
299
|
-
retries: 2,
|
|
300
|
-
multiUrl: true,
|
|
301
|
-
skipProxy: true,
|
|
302
|
-
},
|
|
303
|
-
|
|
304
|
-
{
|
|
305
|
-
key: 'luna-dub',
|
|
306
|
-
label: 'Luna (Dub)',
|
|
307
|
-
sourceFile: 'luna',
|
|
308
|
-
proxyParam: 'ludub',
|
|
309
|
-
subtype: 'dub',
|
|
310
|
-
timeout: 25000,
|
|
311
|
-
jitter: 500,
|
|
312
|
-
retries: 2,
|
|
313
|
-
multiUrl: true,
|
|
314
|
-
skipProxy: true,
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
{
|
|
318
|
-
key: 'mapple',
|
|
319
|
-
label: 'Mapple',
|
|
320
|
-
sourceFile: 'mapple',
|
|
321
|
-
proxyParam: 'mp',
|
|
322
|
-
timeout: 15000,
|
|
323
|
-
retries: 1,
|
|
324
|
-
jitter: 0
|
|
325
|
-
},
|
|
326
|
-
|
|
327
|
-
{
|
|
328
|
-
key: 'meowtv',
|
|
329
|
-
label: 'MeowTV',
|
|
330
|
-
sourceFile: 'meowtv',
|
|
331
|
-
proxyParam: 'mt',
|
|
195
|
+
key: 'movienight',
|
|
196
|
+
label: 'MovieNight',
|
|
197
|
+
sourceFile: 'movienight',
|
|
198
|
+
proxyParam: 'mn',
|
|
332
199
|
timeout: 20000,
|
|
333
200
|
jitter: 500,
|
|
334
201
|
retries: 2,
|
|
335
202
|
multiUrl: true,
|
|
336
|
-
skipProxy: true
|
|
203
|
+
skipProxy: true,
|
|
204
|
+
cdnHeaders: [{
|
|
205
|
+
pattern: /movienig\.ht/i,
|
|
206
|
+
headers: {
|
|
207
|
+
Referer: 'https://movienig.ht/',
|
|
208
|
+
Origin: 'https://movienig.ht',
|
|
209
|
+
},
|
|
210
|
+
}],
|
|
337
211
|
},
|
|
338
212
|
|
|
339
213
|
{
|
|
340
|
-
key: '
|
|
341
|
-
label: '
|
|
342
|
-
sourceFile: '
|
|
343
|
-
proxyParam: '
|
|
214
|
+
key: 'movy',
|
|
215
|
+
label: 'Movy',
|
|
216
|
+
sourceFile: 'movy',
|
|
217
|
+
proxyParam: 'mv',
|
|
344
218
|
timeout: 25000,
|
|
345
219
|
jitter: 500,
|
|
346
220
|
retries: 2,
|
|
347
221
|
multiUrl: true,
|
|
348
222
|
skipProxy: true,
|
|
223
|
+
cdnHeaders: [{
|
|
224
|
+
pattern: /wecollege\.net|movy\.bz/i,
|
|
225
|
+
headers: {
|
|
226
|
+
Referer: 'https://www.movy.bz/',
|
|
227
|
+
Origin: 'https://www.movy.bz',
|
|
228
|
+
},
|
|
229
|
+
}],
|
|
349
230
|
},
|
|
350
231
|
|
|
351
232
|
{
|
|
@@ -372,28 +253,6 @@ export const SOURCES = [
|
|
|
372
253
|
multiUrl: true,
|
|
373
254
|
},
|
|
374
255
|
|
|
375
|
-
{
|
|
376
|
-
key: 'nova',
|
|
377
|
-
label: 'Nova',
|
|
378
|
-
sourceFile: 'nova',
|
|
379
|
-
proxyParam: 'nv',
|
|
380
|
-
timeout: 25000,
|
|
381
|
-
jitter: 500,
|
|
382
|
-
retries: 1,
|
|
383
|
-
multiUrl: true,
|
|
384
|
-
},
|
|
385
|
-
|
|
386
|
-
{
|
|
387
|
-
key: 'megasource',
|
|
388
|
-
label: 'MegaSource',
|
|
389
|
-
sourceFile: 'megasource',
|
|
390
|
-
proxyParam: 'mg',
|
|
391
|
-
timeout: 25000,
|
|
392
|
-
jitter: 500,
|
|
393
|
-
retries: 1,
|
|
394
|
-
multiUrl: true,
|
|
395
|
-
},
|
|
396
|
-
|
|
397
256
|
{
|
|
398
257
|
key: 'purstream',
|
|
399
258
|
sourceFile: 'purstream',
|
|
@@ -417,52 +276,32 @@ export const SOURCES = [
|
|
|
417
276
|
},
|
|
418
277
|
|
|
419
278
|
{
|
|
420
|
-
key: '
|
|
421
|
-
label: '
|
|
422
|
-
sourceFile: '
|
|
423
|
-
proxyParam: '
|
|
279
|
+
key: 'streamaggregator',
|
|
280
|
+
label: 'StreamAggregator',
|
|
281
|
+
sourceFile: 'streamaggregator',
|
|
282
|
+
proxyParam: 'sa',
|
|
424
283
|
timeout: 25000,
|
|
425
284
|
jitter: 500,
|
|
426
|
-
retries: 1,
|
|
427
|
-
multiUrl: true
|
|
428
|
-
},
|
|
429
|
-
|
|
430
|
-
{
|
|
431
|
-
key: 'vidcore',
|
|
432
|
-
sourceFile: 'vidcore',
|
|
433
|
-
label: 'Vidcore',
|
|
434
|
-
proxyParam: 'vc',
|
|
435
|
-
timeout: 30000,
|
|
436
|
-
jitter: 500,
|
|
437
285
|
retries: 2,
|
|
438
|
-
sourcesTimeout: 10000,
|
|
439
|
-
},
|
|
440
|
-
|
|
441
|
-
{
|
|
442
|
-
key: 'videasy',
|
|
443
|
-
label: 'Videasy',
|
|
444
|
-
sourceFile: 'videasy',
|
|
445
|
-
proxyParam: 'vy',
|
|
446
|
-
timeout: 40000,
|
|
447
|
-
sourcesTimeout: 10000,
|
|
448
|
-
jitter: 900,
|
|
449
|
-
retries: 3,
|
|
450
286
|
multiUrl: true,
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
287
|
+
skipProxy: true,
|
|
288
|
+
cdnHeaders: [{
|
|
289
|
+
pattern: /streamaggregator\.in/i,
|
|
290
|
+
headers: {
|
|
291
|
+
Referer: 'https://streamaggregator.in/',
|
|
292
|
+
Origin: 'https://streamaggregator.in',
|
|
293
|
+
},
|
|
294
|
+
}],
|
|
456
295
|
},
|
|
457
|
-
|
|
458
296
|
{
|
|
459
|
-
key: '
|
|
460
|
-
label: '
|
|
461
|
-
sourceFile: '
|
|
462
|
-
proxyParam: '
|
|
463
|
-
timeout:
|
|
297
|
+
key: 'vidapi',
|
|
298
|
+
label: 'VidAPI',
|
|
299
|
+
sourceFile: 'vidapi',
|
|
300
|
+
proxyParam: 'va',
|
|
301
|
+
timeout: 25000,
|
|
464
302
|
jitter: 500,
|
|
465
303
|
retries: 1,
|
|
304
|
+
multiUrl: true
|
|
466
305
|
},
|
|
467
306
|
|
|
468
307
|
{
|
|
@@ -487,7 +326,6 @@ export const SOURCES = [
|
|
|
487
326
|
retries: 2,
|
|
488
327
|
skipProxy: true,
|
|
489
328
|
multiUrl: true,
|
|
490
|
-
disabled: true, // Temporarily disabled because their site is down, all streams are returning 403's
|
|
491
329
|
},
|
|
492
330
|
|
|
493
331
|
{
|
|
@@ -603,25 +441,22 @@ export const SOURCES = [
|
|
|
603
441
|
},
|
|
604
442
|
|
|
605
443
|
{
|
|
606
|
-
key: '
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
proxyParam: '
|
|
610
|
-
timeout: 20000,
|
|
611
|
-
jitter: 500,
|
|
612
|
-
retries: 2,
|
|
613
|
-
skipProxy: true,
|
|
614
|
-
},
|
|
615
|
-
|
|
616
|
-
{
|
|
617
|
-
key: 'zxcstream',
|
|
618
|
-
label: 'ZxcStream',
|
|
619
|
-
sourceFile: 'zxcstream',
|
|
620
|
-
proxyParam: 'zxc',
|
|
444
|
+
key: 'xdownloader',
|
|
445
|
+
label: 'XDownloader',
|
|
446
|
+
sourceFile: 'xdownloader',
|
|
447
|
+
proxyParam: 'xd',
|
|
621
448
|
timeout: 25000,
|
|
622
449
|
jitter: 500,
|
|
623
450
|
retries: 2,
|
|
624
451
|
multiUrl: true,
|
|
452
|
+
skipProxy: true,
|
|
453
|
+
cdnHeaders: [{
|
|
454
|
+
pattern: /films365\.org/i,
|
|
455
|
+
headers: {
|
|
456
|
+
Referer: 'https://www.films365.org/',
|
|
457
|
+
Origin: 'https://www.films365.org',
|
|
458
|
+
},
|
|
459
|
+
}],
|
|
625
460
|
},
|
|
626
461
|
|
|
627
462
|
];
|
|
@@ -1,12 +1,53 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export async function fetchDownloads(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import SOURCES from "../config.js";
|
|
2
|
+
|
|
3
|
+
export async function fetchDownloads(sdkOrId, idOrS = null, sOrE = null, maybeE = null) {
|
|
4
|
+
let sdk = null;
|
|
5
|
+
let id = sdkOrId;
|
|
6
|
+
let s = idOrS;
|
|
7
|
+
let e = sOrE;
|
|
8
|
+
|
|
9
|
+
if (sdkOrId && typeof sdkOrId === 'object' && typeof sdkOrId.getStream === 'function') {
|
|
10
|
+
sdk = sdkOrId;
|
|
11
|
+
id = idOrS;
|
|
12
|
+
s = sOrE;
|
|
13
|
+
e = maybeE;
|
|
11
14
|
}
|
|
15
|
+
|
|
16
|
+
if (!sdk || !id) return [];
|
|
17
|
+
|
|
18
|
+
const activeSources = SOURCES.filter(cfg => !cfg.disabled && cfg.skipProxy);
|
|
19
|
+
const seenUrls = new Set();
|
|
20
|
+
const downloads = [];
|
|
21
|
+
|
|
22
|
+
const results = await Promise.allSettled(
|
|
23
|
+
activeSources.map(async (cfg) => {
|
|
24
|
+
try {
|
|
25
|
+
const res = await sdk.getStream(cfg.key, id, s, e);
|
|
26
|
+
if (!res) return;
|
|
27
|
+
|
|
28
|
+
const items = Array.isArray(res.allUrls) && res.allUrls.length > 0
|
|
29
|
+
? res.allUrls
|
|
30
|
+
: (res.url ? [{ url: res.url, label: cfg.label }] : []);
|
|
31
|
+
|
|
32
|
+
for (const item of items) {
|
|
33
|
+
if (!item?.url || typeof item.url !== 'string') continue;
|
|
34
|
+
const url = item.url.trim();
|
|
35
|
+
|
|
36
|
+
if (!url.startsWith('http') || url.includes('.m3u8')) continue;
|
|
37
|
+
if (!/\.mp4(\?|$)/i.test(url) && !url.includes('.mp4')) continue;
|
|
38
|
+
if (seenUrls.has(url)) continue;
|
|
39
|
+
|
|
40
|
+
seenUrls.add(url);
|
|
41
|
+
|
|
42
|
+
downloads.push({
|
|
43
|
+
source: cfg.key,
|
|
44
|
+
label: item.label || cfg.label,
|
|
45
|
+
url,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
} catch { }
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
return downloads;
|
|
12
53
|
}
|
package/src/sdk.d.ts
CHANGED
package/src/sdk.js
CHANGED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { getUA } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const SERVICE_ORIGIN = 'https://st.111477.xyz';
|
|
4
|
+
|
|
5
|
+
function generateManifestBaseUrl(tmdbKey) {
|
|
6
|
+
let config = 'https://a.111477.xyz/::sort=file-desc::limit=3';
|
|
7
|
+
if (tmdbKey) {
|
|
8
|
+
config += `::tmdb=${tmdbKey}`;
|
|
9
|
+
}
|
|
10
|
+
const b64 = Buffer.from(config, 'utf8')
|
|
11
|
+
.toString('base64')
|
|
12
|
+
.replace(/\+/g, '-')
|
|
13
|
+
.replace(/\//g, '_')
|
|
14
|
+
.replace(/=+$/, '');
|
|
15
|
+
return `${SERVICE_ORIGIN}/config/${b64}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function resolveImdbId(sdk, id, isTv) {
|
|
19
|
+
const apiKey = sdk?.tmdbApiKey || process.env.TMDB_API_KEY;
|
|
20
|
+
if (!apiKey) return null;
|
|
21
|
+
const type = isTv ? 'tv' : 'movie';
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetch(`https://api.themoviedb.org/3/${type}/${id}?api_key=${apiKey}&append_to_response=external_ids`, {
|
|
24
|
+
signal: AbortSignal.timeout(6000),
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) return null;
|
|
27
|
+
const data = await res.json();
|
|
28
|
+
return data.imdb_id || data.external_ids?.imdb_id || null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function getStream({ id, s, e, sdk }) {
|
|
35
|
+
const isTv = Boolean(s && e);
|
|
36
|
+
const ua = getUA();
|
|
37
|
+
const apiKey = sdk?.tmdbApiKey || process.env.TMDB_API_KEY;
|
|
38
|
+
|
|
39
|
+
const imdbId = await resolveImdbId(sdk, id, isTv);
|
|
40
|
+
const targetIds = [];
|
|
41
|
+
|
|
42
|
+
if (imdbId && imdbId.startsWith('tt')) {
|
|
43
|
+
targetIds.push(imdbId);
|
|
44
|
+
}
|
|
45
|
+
targetIds.push(`tmdb:${id}`);
|
|
46
|
+
|
|
47
|
+
const addonBase = generateManifestBaseUrl(apiKey);
|
|
48
|
+
const seenUrls = new Set();
|
|
49
|
+
const allUrls = [];
|
|
50
|
+
|
|
51
|
+
const defaultHeaders = {
|
|
52
|
+
'User-Agent': ua,
|
|
53
|
+
Accept: 'application/json, text/plain, */*',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
for (const targetId of targetIds) {
|
|
57
|
+
const endpoint = isTv
|
|
58
|
+
? `${addonBase}/stream/series/${targetId}:${s || 1}:${e || 1}.json`
|
|
59
|
+
: `${addonBase}/stream/movie/${targetId}.json`;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const res = await fetch(endpoint, {
|
|
63
|
+
headers: defaultHeaders,
|
|
64
|
+
signal: AbortSignal.timeout(12000),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!res.ok) continue;
|
|
68
|
+
const data = await res.json();
|
|
69
|
+
|
|
70
|
+
if (Array.isArray(data?.streams) && data.streams.length > 0) {
|
|
71
|
+
for (const item of data.streams) {
|
|
72
|
+
if (!item || typeof item !== 'object') continue;
|
|
73
|
+
const url = String(item.url || '').trim();
|
|
74
|
+
if (!url || !url.startsWith('http') || seenUrls.has(url)) continue;
|
|
75
|
+
|
|
76
|
+
seenUrls.add(url);
|
|
77
|
+
|
|
78
|
+
const rawTitle = item.title ? String(item.title).trim() : '';
|
|
79
|
+
const rawName = item.name ? String(item.name).trim() : '111477';
|
|
80
|
+
const label = rawTitle || rawName;
|
|
81
|
+
|
|
82
|
+
allUrls.push({
|
|
83
|
+
url,
|
|
84
|
+
label,
|
|
85
|
+
headers: defaultHeaders,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (allUrls.length > 0) break;
|
|
90
|
+
}
|
|
91
|
+
} catch { }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (allUrls.length === 0) return null;
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
url: allUrls[0].url,
|
|
98
|
+
allUrls,
|
|
99
|
+
headers: allUrls[0].headers,
|
|
100
|
+
};
|
|
101
|
+
}
|