@vyla-entertainment/sdk 1.20.0 → 1.22.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 +3 -2
- package/src/config.js +99 -67
- package/src/health.js +60 -20
- package/src/sdk.d.ts +94 -121
- package/src/sdk.js +82 -78
- package/src/sources/111477.js +88 -100
- package/src/sources/123anime.js +120 -56
- package/src/sources/3eyedraven.js +82 -135
- package/src/sources/4movies.js +77 -0
- package/src/sources/aether.js +99 -0
- package/src/sources/castle.js +415 -0
- package/src/sources/cinecat.js +37 -18
- package/src/sources/cinemaarmy.js +179 -180
- package/src/sources/cinesrc.js +401 -397
- package/src/sources/cno.js +101 -94
- package/src/sources/dulo.js +134 -149
- package/src/sources/flaxmovies.js +114 -105
- package/src/sources/framextv.js +126 -0
- package/src/sources/frost.js +38 -29
- package/src/sources/fsonline.js +95 -47
- package/src/sources/hdhub.js +43 -36
- package/src/sources/hexa.js +60 -53
- package/src/sources/hyper.js +42 -35
- package/src/sources/kickassanime.js +117 -124
- package/src/sources/kisskh.js +114 -59
- package/src/sources/lmscript.js +72 -70
- package/src/sources/lookmovie.js +80 -79
- package/src/sources/meowtv.js +140 -0
- package/src/sources/movenerds.js +74 -124
- package/src/sources/movy.js +197 -209
- package/src/sources/net79.js +59 -55
- package/src/sources/peestream.js +126 -138
- package/src/sources/pengu.js +46 -49
- package/src/sources/pstream.js +73 -67
- package/src/sources/purstream.js +96 -104
- package/src/sources/rivestream.js +182 -176
- package/src/sources/rivo.js +58 -53
- package/src/sources/streamaggregator.js +114 -128
- package/src/sources/thugtv.js +70 -62
- package/src/sources/vidapi.js +122 -114
- package/src/sources/vidcore.js +14 -122
- package/src/sources/vidfast.js +14 -122
- package/src/sources/vidlink.js +78 -27
- package/src/sources/vidora.js +74 -42
- package/src/sources/vidup.js +14 -122
- package/src/sources/vidvault.js +133 -187
- package/src/sources/vidy.js +192 -187
- package/src/sources/vidzee.js +189 -183
- package/src/sources/vixsrc.js +123 -113
- package/src/sources/watchout.js +60 -46
- package/src/sources/xdownloader.js +127 -128
- package/src/sources/yapgrid.js +68 -62
- package/src/sources/yastream.js +35 -29
- package/src/subtitles.js +105 -122
- package/src/utils/helpers.js +586 -247
- package/src/sources/bcine.js +0 -202
- package/src/sources/cinezo.js +0 -55
- package/src/sources/vidrock.js +0 -145
|
@@ -1,106 +1,115 @@
|
|
|
1
|
-
import { fetchJson } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
export async function getStream(
|
|
4
|
-
const
|
|
5
|
-
const
|
|
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
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
1
|
+
import { fetchJson } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
export async function getStream(args) {
|
|
4
|
+
const { id, s, e } = args || {};
|
|
5
|
+
const isTv = s != null && e != null;
|
|
6
|
+
const allUrls = [];
|
|
7
|
+
|
|
8
|
+
const endpoints = [
|
|
9
|
+
async () => {
|
|
10
|
+
const url = isTv
|
|
11
|
+
? `https://themoviebox.uk/api/resolve?type=tv&id=${id}&season=${s}&episode=${e}`
|
|
12
|
+
: `https://themoviebox.uk/api/resolve?type=movie&id=${id}`;
|
|
13
|
+
const res = await fetchJson(url);
|
|
14
|
+
if (res?.success && Array.isArray(res.sources)) {
|
|
15
|
+
for (const item of res.sources) {
|
|
16
|
+
const streamUrl = item.url || item.original_url;
|
|
17
|
+
if (streamUrl) {
|
|
18
|
+
allUrls.push({
|
|
19
|
+
url: streamUrl,
|
|
20
|
+
server: `TheMovieBox - ${item.server || item.provider || 'Server'}`,
|
|
21
|
+
quality: 'Auto',
|
|
22
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
23
|
+
headers: {
|
|
24
|
+
Referer: 'https://themoviebox.uk/',
|
|
25
|
+
Origin: 'https://themoviebox.uk',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
async () => {
|
|
34
|
+
const url = isTv
|
|
35
|
+
? `https://pro2.nabilekson.workers.dev/tv/${id}/${s}/${e}`
|
|
36
|
+
: `https://pro2.nabilekson.workers.dev/movie/${id}`;
|
|
37
|
+
const res = await fetchJson(url);
|
|
38
|
+
if (res?.success && Array.isArray(res.primarySources)) {
|
|
39
|
+
for (const item of res.primarySources) {
|
|
40
|
+
const streamUrl = item.url || item.originalUrl;
|
|
41
|
+
if (streamUrl) {
|
|
42
|
+
allUrls.push({
|
|
43
|
+
url: streamUrl,
|
|
44
|
+
server: `CineBros - ${item.name || item.quality || 'Server'}`,
|
|
45
|
+
quality: item.quality || 'Auto',
|
|
46
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
47
|
+
headers: item.headers || {
|
|
48
|
+
Referer: 'https://pro2.nabilekson.workers.dev/',
|
|
49
|
+
Origin: 'https://pro2.nabilekson.workers.dev',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
async () => {
|
|
58
|
+
const url = isTv
|
|
59
|
+
? `https://praxi.nabilekson.workers.dev/tv/${id}/${s}/${e}`
|
|
60
|
+
: `https://praxi.nabilekson.workers.dev/movie/${id}`;
|
|
61
|
+
const res = await fetchJson(url);
|
|
62
|
+
if (res?.success && Array.isArray(res.primarySources)) {
|
|
63
|
+
for (const item of res.primarySources) {
|
|
64
|
+
const streamUrl = item.url || item.originalUrl;
|
|
65
|
+
if (streamUrl) {
|
|
66
|
+
allUrls.push({
|
|
67
|
+
url: streamUrl,
|
|
68
|
+
server: `Praxi - ${item.name || item.providerName || 'Server'}`,
|
|
69
|
+
quality: 'Auto',
|
|
70
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
71
|
+
headers: item.headers || {
|
|
72
|
+
Referer: 'https://praxi.nabilekson.workers.dev/',
|
|
73
|
+
Origin: 'https://praxi.nabilekson.workers.dev',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
async () => {
|
|
82
|
+
const url = isTv
|
|
83
|
+
? `https://freakyniki.elaxo.lol/?tmdb_id=${id}&season=${s}&episode=${e}`
|
|
84
|
+
: `https://freakyniki.elaxo.lol/?tmdb_id=${id}`;
|
|
85
|
+
const res = await fetchJson(url);
|
|
86
|
+
if (Array.isArray(res?.streams)) {
|
|
87
|
+
for (const item of res.streams) {
|
|
88
|
+
const streamUrl = item.url || item.raw_url;
|
|
89
|
+
if (streamUrl) {
|
|
90
|
+
allUrls.push({
|
|
91
|
+
url: streamUrl,
|
|
92
|
+
server: `FreakyNiki - ${item.server || item.provider || 'Server'}`,
|
|
93
|
+
quality: 'Auto',
|
|
94
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
95
|
+
headers: {
|
|
96
|
+
Referer: 'https://freakyniki.elaxo.lol/',
|
|
97
|
+
Origin: 'https://freakyniki.elaxo.lol',
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
await Promise.allSettled(endpoints.map(fn => fn().catch(() => { })));
|
|
107
|
+
|
|
108
|
+
if (!allUrls.length) return null;
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
url: allUrls[0].url,
|
|
112
|
+
headers: allUrls[0].headers,
|
|
113
|
+
allUrls,
|
|
114
|
+
};
|
|
106
115
|
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const FRAMEX_BASE = 'https://api.framextv.cc';
|
|
2
|
+
const STREAMOS_BASE = 'https://api.streamos.top';
|
|
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 FRAMEX_HEADERS = {
|
|
6
|
+
'User-Agent': UA,
|
|
7
|
+
Referer: 'https://framextv.cc/',
|
|
8
|
+
Origin: 'https://framextv.cc',
|
|
9
|
+
Accept: 'application/json, text/plain, */*',
|
|
10
|
+
'Accept-Language': 'en-US,en;q=0.9',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const STREAMOS_HEADERS = {
|
|
14
|
+
'User-Agent': UA,
|
|
15
|
+
Referer: 'https://streamos.top/',
|
|
16
|
+
Origin: 'https://streamos.top',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const STREAMOS_SERVERS = [
|
|
20
|
+
'auto',
|
|
21
|
+
'miami',
|
|
22
|
+
'boise',
|
|
23
|
+
'vegas',
|
|
24
|
+
'reno',
|
|
25
|
+
'oakland',
|
|
26
|
+
'seattle',
|
|
27
|
+
'phoenix',
|
|
28
|
+
'atlanta',
|
|
29
|
+
'portland',
|
|
30
|
+
'austin',
|
|
31
|
+
'dallas',
|
|
32
|
+
'tampa',
|
|
33
|
+
'orlando',
|
|
34
|
+
'munich',
|
|
35
|
+
'berlin',
|
|
36
|
+
'france',
|
|
37
|
+
'india',
|
|
38
|
+
'mexico',
|
|
39
|
+
'delhi',
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
export async function getStream(args) {
|
|
43
|
+
const { id, s, e } = args || {};
|
|
44
|
+
const isTv = s != null && e != null;
|
|
45
|
+
|
|
46
|
+
const framexQuery = isTv
|
|
47
|
+
? `type=tv&id=${id}&season=${s}&episode=${e}&codecs=hevc`
|
|
48
|
+
: `type=movie&id=${id}&codecs=hevc`;
|
|
49
|
+
|
|
50
|
+
const framexUrls = [
|
|
51
|
+
`${FRAMEX_BASE}/api/stream?${framexQuery}`,
|
|
52
|
+
`${FRAMEX_BASE}/api/stream?${framexQuery}&provider=sparky`,
|
|
53
|
+
`${FRAMEX_BASE}/api/stream?${framexQuery}&provider=titan`,
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const streamOsBaseQuery = isTv
|
|
57
|
+
? `id=${id}&season=${s}&episode=${e}&kind=tv`
|
|
58
|
+
: `id=${id}&kind=movie`;
|
|
59
|
+
|
|
60
|
+
const allUrls = [];
|
|
61
|
+
const seen = new Set();
|
|
62
|
+
|
|
63
|
+
const framexPromises = Promise.all(
|
|
64
|
+
framexUrls.map(url =>
|
|
65
|
+
fetch(url, { headers: FRAMEX_HEADERS })
|
|
66
|
+
.then(r => (r.ok ? r.json() : null))
|
|
67
|
+
.catch(() => null)
|
|
68
|
+
)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const streamOsChecks = Promise.all(
|
|
72
|
+
STREAMOS_SERVERS.slice(0, 8).map(async server => {
|
|
73
|
+
const serverParam = server === 'auto' ? '' : `&server=${server}`;
|
|
74
|
+
const url = `${STREAMOS_BASE}/api/relay/hls?${streamOsBaseQuery}${serverParam}`;
|
|
75
|
+
try {
|
|
76
|
+
const res = await fetch(url, { method: 'HEAD', headers: STREAMOS_HEADERS });
|
|
77
|
+
if (res.ok) {
|
|
78
|
+
return {
|
|
79
|
+
url,
|
|
80
|
+
server: `StreamOS - ${server.toUpperCase()}`,
|
|
81
|
+
quality: '1080p',
|
|
82
|
+
type: 'hls',
|
|
83
|
+
headers: STREAMOS_HEADERS,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
} catch { }
|
|
87
|
+
return null;
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const [framexResults, streamOsResults] = await Promise.all([framexPromises, streamOsChecks]);
|
|
92
|
+
|
|
93
|
+
for (const data of framexResults) {
|
|
94
|
+
if (!data?.success || !Array.isArray(data.sources)) continue;
|
|
95
|
+
for (const src of data.sources) {
|
|
96
|
+
if (!src?.url || seen.has(src.url)) continue;
|
|
97
|
+
seen.add(src.url);
|
|
98
|
+
allUrls.push({
|
|
99
|
+
url: src.url,
|
|
100
|
+
server: `FrameX - ${src.server || data.provider || 'Direct'}`,
|
|
101
|
+
quality: src.quality || 'Auto',
|
|
102
|
+
type: src.type || (src.url.includes('.m3u8') ? 'hls' : 'mp4'),
|
|
103
|
+
headers: {
|
|
104
|
+
'User-Agent': UA,
|
|
105
|
+
Referer: 'https://framextv.cc/',
|
|
106
|
+
Origin: 'https://framextv.cc',
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const stream of streamOsResults) {
|
|
113
|
+
if (stream && !seen.has(stream.url)) {
|
|
114
|
+
seen.add(stream.url);
|
|
115
|
+
allUrls.push(stream);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!allUrls.length) return null;
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
url: allUrls[0].url,
|
|
123
|
+
headers: allUrls[0].headers,
|
|
124
|
+
allUrls,
|
|
125
|
+
};
|
|
126
|
+
}
|
package/src/sources/frost.js
CHANGED
|
@@ -1,30 +1,39 @@
|
|
|
1
|
-
import { fetchJson, resolveImdbId } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
import { fetchJson, resolveImdbId, resolveTmdbKey } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://froststream.cloutteam.com';
|
|
4
|
+
|
|
5
|
+
export async function getStream(args) {
|
|
6
|
+
const { id, s, e, sdk } = args || {};
|
|
7
|
+
const isTv = s != null && e != null;
|
|
8
|
+
const type = isTv ? 'series' : 'movie';
|
|
9
|
+
const apiKey = resolveTmdbKey(args, sdk);
|
|
10
|
+
|
|
11
|
+
const imdb = await resolveImdbId(id, isTv, apiKey);
|
|
12
|
+
if (!imdb) return null;
|
|
13
|
+
|
|
14
|
+
const url = isTv
|
|
15
|
+
? `${BASE_URL}/stream/series/${imdb}:${s}:${e}.json`
|
|
16
|
+
: `${BASE_URL}/stream/movie/${imdb}.json`;
|
|
17
|
+
|
|
18
|
+
const res = await fetchJson(url).catch(() => null);
|
|
19
|
+
if (!res || !Array.isArray(res.streams) || !res.streams.length) return null;
|
|
20
|
+
|
|
21
|
+
const allUrls = res.streams
|
|
22
|
+
.filter(st => st.url)
|
|
23
|
+
.map(st => ({
|
|
24
|
+
url: st.url,
|
|
25
|
+
server: `Frost - ${st.name || 'Server'}${st.title ? ` - ${st.title}` : ''}`,
|
|
26
|
+
quality: 'Auto',
|
|
27
|
+
type: st.url.includes('.m3u8') ? 'hls' : 'mp4',
|
|
28
|
+
headers: st.behaviorHints?.proxyHeaders?.request || undefined,
|
|
29
|
+
skipProxy: st.behaviorHints?.notWebReady === false,
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
if (!allUrls.length) return null;
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
url: allUrls[0].url,
|
|
36
|
+
headers: allUrls[0].headers,
|
|
37
|
+
allUrls,
|
|
38
|
+
};
|
|
30
39
|
}
|
package/src/sources/fsonline.js
CHANGED
|
@@ -1,48 +1,96 @@
|
|
|
1
|
-
import { fetchText,
|
|
2
|
-
|
|
3
|
-
const ORIGIN = 'https://www3.fsonline.app';
|
|
4
|
-
const AJAX_URL = `${ORIGIN}/wp-admin/admin-ajax.php`;
|
|
5
|
-
const HEADERS = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
1
|
+
import { fetchText, getTmdbMetadata, resolveTmdbKey, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const ORIGIN = 'https://www3.fsonline.app';
|
|
4
|
+
const AJAX_URL = `${ORIGIN}/wp-admin/admin-ajax.php`;
|
|
5
|
+
const HEADERS = {
|
|
6
|
+
'User-Agent': USER_AGENT,
|
|
7
|
+
Origin: ORIGIN,
|
|
8
|
+
Referer: `${ORIGIN}/`,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export async function getStream(args) {
|
|
12
|
+
const { id, s, e, sdk } = args || {};
|
|
13
|
+
const isTv = s != null && e != null;
|
|
14
|
+
const apiKey = resolveTmdbKey(args, sdk);
|
|
15
|
+
if (!apiKey) return null;
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const meta = await getTmdbMetadata(id, isTv, apiKey);
|
|
19
|
+
if (!meta?.titles?.length) return null;
|
|
20
|
+
|
|
21
|
+
const query = meta.titles[0] + (meta.year ? ` ${meta.year}` : '');
|
|
22
|
+
const searchHtml = await fetchText(`${ORIGIN}/?s=${encodeURIComponent(query)}`, { headers: HEADERS });
|
|
23
|
+
const typeFolder = isTv ? 'seriale' : 'film';
|
|
24
|
+
const linkMatch = searchHtml.match(new RegExp(`href=["'](https?://www3\\.fsonline\\.app/${typeFolder}/([^"'/]+)/)["']`, 'i'));
|
|
25
|
+
if (!linkMatch) return null;
|
|
26
|
+
|
|
27
|
+
const targetPageUrl = isTv
|
|
28
|
+
? `${ORIGIN}/episoade/${linkMatch[2].replace(/-\d{4}$/, '')}-sezonul-${s}-episodul-${e}/`
|
|
29
|
+
: linkMatch[1];
|
|
30
|
+
|
|
31
|
+
const pageHtml = await fetchText(targetPageUrl, { headers: HEADERS });
|
|
32
|
+
const movieId = (pageHtml.match(/movie-id=['"]([^'"]+)['"]/) || pageHtml.match(/movie-id=([^ >]+)/))?.[1];
|
|
33
|
+
if (!movieId) return null;
|
|
34
|
+
|
|
35
|
+
const ajaxHtml = await fetchText(AJAX_URL, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
...HEADERS,
|
|
39
|
+
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
40
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
41
|
+
Referer: targetPageUrl,
|
|
42
|
+
},
|
|
43
|
+
body: `action=lazy_player&movieID=${movieId}`,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const allUrls = [];
|
|
47
|
+
let idx = 0;
|
|
48
|
+
while ((idx = ajaxHtml.indexOf('data-vs="', idx)) !== -1) {
|
|
49
|
+
const embedStart = idx + 9;
|
|
50
|
+
const embedEnd = ajaxHtml.indexOf('"', embedStart);
|
|
51
|
+
const embedUrl = ajaxHtml.slice(embedStart, embedEnd);
|
|
52
|
+
const spanStart = ajaxHtml.indexOf('<span>', embedEnd);
|
|
53
|
+
const spanEnd = ajaxHtml.indexOf('</span>', spanStart);
|
|
54
|
+
const serverLabel = ajaxHtml.slice(spanStart + 6, spanEnd).trim().toLowerCase();
|
|
55
|
+
|
|
56
|
+
if (serverLabel.includes('filesun')) {
|
|
57
|
+
try {
|
|
58
|
+
const rHtml = await fetchText(embedUrl, {
|
|
59
|
+
headers: { Referer: ORIGIN, 'User-Agent': USER_AGENT },
|
|
60
|
+
});
|
|
61
|
+
const m3u8Match = rHtml.match(/file:\s*["'](https?:\/\/[^"']+\.m3u8[^"']*)["']/) || rHtml.match(/["']?file["']?:\s*["'](https?:\/\/[^"']+)["']/);
|
|
62
|
+
if (m3u8Match) {
|
|
63
|
+
const streamUrl = m3u8Match[1].replace(/\\\//g, '/');
|
|
64
|
+
allUrls.push({
|
|
65
|
+
url: streamUrl,
|
|
66
|
+
server: 'FSOnline - FileSuN',
|
|
67
|
+
quality: 'Auto',
|
|
68
|
+
type: 'hls',
|
|
69
|
+
headers: {
|
|
70
|
+
Referer: embedUrl,
|
|
71
|
+
Origin: 'https://player.fsonline.app',
|
|
72
|
+
'User-Agent': USER_AGENT,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
} catch { }
|
|
77
|
+
}
|
|
78
|
+
idx = spanEnd;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!allUrls.length) return null;
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
url: allUrls[0].url,
|
|
85
|
+
headers: allUrls[0].headers,
|
|
86
|
+
allUrls,
|
|
87
|
+
};
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function getSources(args) {
|
|
94
|
+
const stream = await getStream(args);
|
|
95
|
+
return stream?.allUrls ? [...new Set(stream.allUrls.map(u => u.server))] : [];
|
|
48
96
|
}
|