@vyla-entertainment/sdk 1.10.0 → 1.12.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 +212 -98
- 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/4khdhub.js +324 -0
- package/src/sources/bcine.js +202 -0
- package/src/sources/cinesrc.js +212 -0
- package/src/sources/cinesu.js +148 -0
- package/src/sources/downloadeverything.js +338 -0
- package/src/sources/meowtv.js +42 -3
- package/src/sources/movienight.js +117 -0
- package/src/sources/movy.js +282 -0
- package/src/sources/pstream.js +68 -0
- package/src/sources/purstream.js +2 -2
- package/src/sources/streamaggregator.js +127 -0
- package/src/sources/vadapav.js +85 -0
- package/src/sources/vidvault.js +131 -57
- package/src/sources/vuflix.js +249 -0
- 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/mapple.js +0 -151
- package/src/sources/megasource.js +0 -47
- package/src/sources/nova.js +0 -46
- package/src/sources/videasy.js +0 -94
- package/src/sources/vidrift.js +0 -95
- package/src/sources/vidsync.js +0 -38
- package/src/sources/xpass.js +0 -40
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
|
|
@@ -6,6 +6,18 @@
|
|
|
6
6
|
// Fshare/Fsonic Tested: 155 ( they don't have Michael )
|
|
7
7
|
|
|
8
8
|
export const SOURCES = [
|
|
9
|
+
{
|
|
10
|
+
key: '4khdhub',
|
|
11
|
+
label: '4KHDHub',
|
|
12
|
+
sourceFile: '4khdhub',
|
|
13
|
+
proxyParam: 'khd',
|
|
14
|
+
timeout: 35000,
|
|
15
|
+
jitter: 500,
|
|
16
|
+
retries: 1,
|
|
17
|
+
multiUrl: true,
|
|
18
|
+
skipProxy: true,
|
|
19
|
+
},
|
|
20
|
+
|
|
9
21
|
{
|
|
10
22
|
key: '123anime',
|
|
11
23
|
label: '123Anime',
|
|
@@ -25,6 +37,25 @@ export const SOURCES = [
|
|
|
25
37
|
},],
|
|
26
38
|
},
|
|
27
39
|
|
|
40
|
+
{
|
|
41
|
+
key: '111477',
|
|
42
|
+
label: '111477',
|
|
43
|
+
sourceFile: '111477',
|
|
44
|
+
proxyParam: 'a11',
|
|
45
|
+
timeout: 25000,
|
|
46
|
+
jitter: 500,
|
|
47
|
+
retries: 2,
|
|
48
|
+
multiUrl: true,
|
|
49
|
+
skipProxy: true,
|
|
50
|
+
cdnHeaders: [{
|
|
51
|
+
pattern: /111477\.xyz/i,
|
|
52
|
+
headers: {
|
|
53
|
+
Referer: 'https://st.111477.xyz/',
|
|
54
|
+
Origin: 'https://st.111477.xyz',
|
|
55
|
+
},
|
|
56
|
+
}],
|
|
57
|
+
},
|
|
58
|
+
|
|
28
59
|
{
|
|
29
60
|
key: 'anihq-sub',
|
|
30
61
|
label: 'AniHQ (Sub)',
|
|
@@ -70,49 +101,92 @@ export const SOURCES = [
|
|
|
70
101
|
},
|
|
71
102
|
|
|
72
103
|
{
|
|
73
|
-
key: '
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
proxyParam: '
|
|
104
|
+
key: 'bcine',
|
|
105
|
+
label: 'Bcine',
|
|
106
|
+
sourceFile: 'bcine',
|
|
107
|
+
proxyParam: 'bc',
|
|
77
108
|
timeout: 25000,
|
|
78
109
|
jitter: 500,
|
|
79
110
|
retries: 2,
|
|
80
|
-
skipProxy: true,
|
|
81
|
-
skipVerify: true,
|
|
82
111
|
multiUrl: true,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
112
|
+
cdnHeaders: [{
|
|
113
|
+
pattern: /1embed\.cc|videasy\.to/i,
|
|
114
|
+
headers: {
|
|
115
|
+
Referer: 'https://bcine.ru/',
|
|
116
|
+
Origin: 'https://bcine.ru',
|
|
117
|
+
},
|
|
118
|
+
}],
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
key: 'cinejoy',
|
|
123
|
+
label: 'Cinejoy',
|
|
124
|
+
sourceFile: 'cinejoy',
|
|
125
|
+
proxyParam: 'cj',
|
|
126
|
+
timeout: 30000,
|
|
127
|
+
jitter: 500,
|
|
128
|
+
retries: 1,
|
|
129
|
+
multiUrl: true,
|
|
130
|
+
skipProxy: true,
|
|
87
131
|
},
|
|
88
132
|
|
|
89
133
|
{
|
|
90
|
-
key: '
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
proxyParam: '
|
|
134
|
+
key: 'cinesrc',
|
|
135
|
+
label: 'CineSrc',
|
|
136
|
+
sourceFile: 'cinesrc',
|
|
137
|
+
proxyParam: 'csr',
|
|
94
138
|
timeout: 25000,
|
|
95
139
|
jitter: 500,
|
|
96
140
|
retries: 2,
|
|
141
|
+
multiUrl: true,
|
|
97
142
|
skipProxy: true,
|
|
98
143
|
skipVerify: true,
|
|
144
|
+
cdnHeaders: [{
|
|
145
|
+
pattern: /glendale-plumbing\.com|1embed\.cc|bright\d+\.online/i,
|
|
146
|
+
headers: {
|
|
147
|
+
Referer: 'https://cinesrc.st/',
|
|
148
|
+
Origin: 'https://cinesrc.st',
|
|
149
|
+
},
|
|
150
|
+
}],
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
{
|
|
154
|
+
key: 'cinesu',
|
|
155
|
+
label: 'CineSu',
|
|
156
|
+
sourceFile: 'cinesu',
|
|
157
|
+
proxyParam: 'cs',
|
|
158
|
+
timeout: 25000,
|
|
159
|
+
jitter: 500,
|
|
160
|
+
retries: 2,
|
|
99
161
|
multiUrl: true,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
162
|
+
skipProxy: true,
|
|
163
|
+
skipVerify: true,
|
|
164
|
+
cdnHeaders: [{
|
|
165
|
+
pattern: /glendale-plumbing\.com/i,
|
|
166
|
+
headers: {
|
|
167
|
+
Referer: 'https://cine.su/',
|
|
168
|
+
Origin: 'https://cine.su',
|
|
169
|
+
},
|
|
170
|
+
}],
|
|
104
171
|
},
|
|
105
172
|
|
|
106
173
|
{
|
|
107
|
-
key: '
|
|
108
|
-
label: '
|
|
109
|
-
sourceFile: '
|
|
110
|
-
proxyParam: '
|
|
111
|
-
timeout:
|
|
174
|
+
key: 'downloadeverything',
|
|
175
|
+
label: 'DownloadEverything',
|
|
176
|
+
sourceFile: 'downloadeverything',
|
|
177
|
+
proxyParam: 'de',
|
|
178
|
+
timeout: 35000,
|
|
112
179
|
jitter: 500,
|
|
113
180
|
retries: 1,
|
|
114
181
|
multiUrl: true,
|
|
115
182
|
skipProxy: true,
|
|
183
|
+
cdnHeaders: [{
|
|
184
|
+
pattern: /cloudflarestorage\.com|pixeldrain\.com|hakunaymatata\.com/i,
|
|
185
|
+
headers: {
|
|
186
|
+
Referer: 'https://downloadeverythingfromeverywhere.com/',
|
|
187
|
+
Origin: 'https://downloadeverythingfromeverywhere.com',
|
|
188
|
+
},
|
|
189
|
+
}],
|
|
116
190
|
},
|
|
117
191
|
|
|
118
192
|
{
|
|
@@ -256,16 +330,6 @@ export const SOURCES = [
|
|
|
256
330
|
skipProxy: true,
|
|
257
331
|
},
|
|
258
332
|
|
|
259
|
-
{
|
|
260
|
-
key: 'mapple',
|
|
261
|
-
label: 'Mapple',
|
|
262
|
-
sourceFile: 'mapple',
|
|
263
|
-
proxyParam: 'mp',
|
|
264
|
-
timeout: 15000,
|
|
265
|
-
retries: 1,
|
|
266
|
-
jitter: 0
|
|
267
|
-
},
|
|
268
|
-
|
|
269
333
|
{
|
|
270
334
|
key: 'meowtv',
|
|
271
335
|
label: 'MeowTV',
|
|
@@ -278,6 +342,44 @@ export const SOURCES = [
|
|
|
278
342
|
skipProxy: true
|
|
279
343
|
},
|
|
280
344
|
|
|
345
|
+
{
|
|
346
|
+
key: 'movienight',
|
|
347
|
+
label: 'MovieNight',
|
|
348
|
+
sourceFile: 'movienight',
|
|
349
|
+
proxyParam: 'mn',
|
|
350
|
+
timeout: 20000,
|
|
351
|
+
jitter: 500,
|
|
352
|
+
retries: 2,
|
|
353
|
+
multiUrl: true,
|
|
354
|
+
skipProxy: true,
|
|
355
|
+
cdnHeaders: [{
|
|
356
|
+
pattern: /movienig\.ht/i,
|
|
357
|
+
headers: {
|
|
358
|
+
Referer: 'https://movienig.ht/',
|
|
359
|
+
Origin: 'https://movienig.ht',
|
|
360
|
+
},
|
|
361
|
+
}],
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
{
|
|
365
|
+
key: 'movy',
|
|
366
|
+
label: 'Movy',
|
|
367
|
+
sourceFile: 'movy',
|
|
368
|
+
proxyParam: 'mv',
|
|
369
|
+
timeout: 25000,
|
|
370
|
+
jitter: 500,
|
|
371
|
+
retries: 2,
|
|
372
|
+
multiUrl: true,
|
|
373
|
+
skipProxy: true,
|
|
374
|
+
cdnHeaders: [{
|
|
375
|
+
pattern: /wecollege\.net|movy\.bz/i,
|
|
376
|
+
headers: {
|
|
377
|
+
Referer: 'https://www.movy.bz/',
|
|
378
|
+
Origin: 'https://www.movy.bz',
|
|
379
|
+
},
|
|
380
|
+
}],
|
|
381
|
+
},
|
|
382
|
+
|
|
281
383
|
{
|
|
282
384
|
key: 'peestream',
|
|
283
385
|
label: 'PeeStream',
|
|
@@ -302,24 +404,13 @@ export const SOURCES = [
|
|
|
302
404
|
skipProxy: true,
|
|
303
405
|
disabled: false, // Enabled, but only returns streams when a manifest is provided
|
|
304
406
|
},
|
|
305
|
-
|
|
306
|
-
{
|
|
307
|
-
key: 'nova',
|
|
308
|
-
label: 'Nova',
|
|
309
|
-
sourceFile: 'nova',
|
|
310
|
-
proxyParam: 'nv',
|
|
311
|
-
timeout: 25000,
|
|
312
|
-
jitter: 500,
|
|
313
|
-
retries: 1,
|
|
314
|
-
multiUrl: true,
|
|
315
|
-
},
|
|
316
|
-
|
|
407
|
+
|
|
317
408
|
{
|
|
318
|
-
key: '
|
|
319
|
-
label: '
|
|
320
|
-
sourceFile: '
|
|
321
|
-
proxyParam: '
|
|
322
|
-
timeout:
|
|
409
|
+
key: 'pstream',
|
|
410
|
+
label: 'PStream',
|
|
411
|
+
sourceFile: 'pstream',
|
|
412
|
+
proxyParam: 'ps',
|
|
413
|
+
timeout: 35000,
|
|
323
414
|
jitter: 500,
|
|
324
415
|
retries: 1,
|
|
325
416
|
multiUrl: true,
|
|
@@ -347,6 +438,44 @@ export const SOURCES = [
|
|
|
347
438
|
multiUrl: true,
|
|
348
439
|
},
|
|
349
440
|
|
|
441
|
+
{
|
|
442
|
+
key: 'streamaggregator',
|
|
443
|
+
label: 'StreamAggregator',
|
|
444
|
+
sourceFile: 'streamaggregator',
|
|
445
|
+
proxyParam: 'sa',
|
|
446
|
+
timeout: 25000,
|
|
447
|
+
jitter: 500,
|
|
448
|
+
retries: 2,
|
|
449
|
+
multiUrl: true,
|
|
450
|
+
skipProxy: true,
|
|
451
|
+
cdnHeaders: [{
|
|
452
|
+
pattern: /streamaggregator\.in/i,
|
|
453
|
+
headers: {
|
|
454
|
+
Referer: 'https://streamaggregator.in/',
|
|
455
|
+
Origin: 'https://streamaggregator.in',
|
|
456
|
+
},
|
|
457
|
+
}],
|
|
458
|
+
},
|
|
459
|
+
|
|
460
|
+
{
|
|
461
|
+
key: 'vadapav',
|
|
462
|
+
label: 'Vadapav',
|
|
463
|
+
sourceFile: 'vadapav',
|
|
464
|
+
proxyParam: 'vp',
|
|
465
|
+
timeout: 25000,
|
|
466
|
+
jitter: 500,
|
|
467
|
+
retries: 2,
|
|
468
|
+
multiUrl: true,
|
|
469
|
+
skipProxy: true,
|
|
470
|
+
cdnHeaders: [{
|
|
471
|
+
pattern: /vadapav\.mov/i,
|
|
472
|
+
headers: {
|
|
473
|
+
Referer: 'https://stremio.vadapav.mov/',
|
|
474
|
+
Origin: 'https://stremio.vadapav.mov',
|
|
475
|
+
},
|
|
476
|
+
}],
|
|
477
|
+
},
|
|
478
|
+
|
|
350
479
|
{
|
|
351
480
|
key: 'vidapi',
|
|
352
481
|
label: 'VidAPI',
|
|
@@ -369,23 +498,6 @@ export const SOURCES = [
|
|
|
369
498
|
sourcesTimeout: 10000,
|
|
370
499
|
},
|
|
371
500
|
|
|
372
|
-
{
|
|
373
|
-
key: 'videasy',
|
|
374
|
-
label: 'Videasy',
|
|
375
|
-
sourceFile: 'videasy',
|
|
376
|
-
proxyParam: 'vy',
|
|
377
|
-
timeout: 40000,
|
|
378
|
-
sourcesTimeout: 10000,
|
|
379
|
-
jitter: 900,
|
|
380
|
-
retries: 3,
|
|
381
|
-
multiUrl: true,
|
|
382
|
-
verifyHeaders: {
|
|
383
|
-
Accept: 'application/json, /; q=0.01',
|
|
384
|
-
Referer: 'https://player.videasy.net/',
|
|
385
|
-
Origin: 'https://player.videasy.net',
|
|
386
|
-
},
|
|
387
|
-
},
|
|
388
|
-
|
|
389
501
|
{
|
|
390
502
|
key: 'vidfast',
|
|
391
503
|
label: 'Vidfast',
|
|
@@ -418,7 +530,6 @@ export const SOURCES = [
|
|
|
418
530
|
retries: 2,
|
|
419
531
|
skipProxy: true,
|
|
420
532
|
multiUrl: true,
|
|
421
|
-
disabled: true, // Temporarily disabled because their site is down, all streams are returning 403's
|
|
422
533
|
},
|
|
423
534
|
|
|
424
535
|
{
|
|
@@ -456,19 +567,6 @@ export const SOURCES = [
|
|
|
456
567
|
skipProxy: true,
|
|
457
568
|
},
|
|
458
569
|
|
|
459
|
-
{
|
|
460
|
-
key: 'vidrift',
|
|
461
|
-
label: 'VidRift',
|
|
462
|
-
sourceFile: 'vidrift',
|
|
463
|
-
proxyParam: 'vr',
|
|
464
|
-
timeout: 20000,
|
|
465
|
-
jitter: 500,
|
|
466
|
-
retries: 2,
|
|
467
|
-
multiUrl: true,
|
|
468
|
-
skipProxy: true,
|
|
469
|
-
disabled: true, // Temporarily disabled because their site is down, embed website does not load
|
|
470
|
-
},
|
|
471
|
-
|
|
472
570
|
{
|
|
473
571
|
key: 'vidrock',
|
|
474
572
|
label: 'VidRock',
|
|
@@ -489,17 +587,6 @@ export const SOURCES = [
|
|
|
489
587
|
},],
|
|
490
588
|
},
|
|
491
589
|
|
|
492
|
-
{
|
|
493
|
-
key: 'vidsync',
|
|
494
|
-
label: 'VidSync',
|
|
495
|
-
sourceFile: 'vidsync',
|
|
496
|
-
proxyParam: 'vs',
|
|
497
|
-
timeout: 20000,
|
|
498
|
-
retries: 2,
|
|
499
|
-
multiUrl: true,
|
|
500
|
-
disabled: true, // Temporarily disabled due to enc dec issues
|
|
501
|
-
},
|
|
502
|
-
|
|
503
590
|
{
|
|
504
591
|
key: 'vidup',
|
|
505
592
|
label: 'VidUp',
|
|
@@ -558,14 +645,41 @@ export const SOURCES = [
|
|
|
558
645
|
},
|
|
559
646
|
|
|
560
647
|
{
|
|
561
|
-
key: '
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
proxyParam: '
|
|
565
|
-
timeout:
|
|
648
|
+
key: 'vuflix',
|
|
649
|
+
label: 'Vuflix',
|
|
650
|
+
sourceFile: 'vuflix',
|
|
651
|
+
proxyParam: 'vfx',
|
|
652
|
+
timeout: 25000,
|
|
653
|
+
jitter: 500,
|
|
654
|
+
retries: 2,
|
|
655
|
+
multiUrl: true,
|
|
656
|
+
skipProxy: true,
|
|
657
|
+
cdnHeaders: [{
|
|
658
|
+
pattern: /vuflix\.co/i,
|
|
659
|
+
headers: {
|
|
660
|
+
Referer: 'https://vuflix.co/',
|
|
661
|
+
Origin: 'https://vuflix.co',
|
|
662
|
+
},
|
|
663
|
+
}],
|
|
664
|
+
},
|
|
665
|
+
|
|
666
|
+
{
|
|
667
|
+
key: 'xdownloader',
|
|
668
|
+
label: 'XDownloader',
|
|
669
|
+
sourceFile: 'xdownloader',
|
|
670
|
+
proxyParam: 'xd',
|
|
671
|
+
timeout: 25000,
|
|
566
672
|
jitter: 500,
|
|
567
673
|
retries: 2,
|
|
674
|
+
multiUrl: true,
|
|
568
675
|
skipProxy: true,
|
|
676
|
+
cdnHeaders: [{
|
|
677
|
+
pattern: /films365\.org/i,
|
|
678
|
+
headers: {
|
|
679
|
+
Referer: 'https://www.films365.org/',
|
|
680
|
+
Origin: 'https://www.films365.org',
|
|
681
|
+
},
|
|
682
|
+
}],
|
|
569
683
|
},
|
|
570
684
|
|
|
571
685
|
];
|
|
@@ -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
|
+
}
|