@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
package/src/sources/hdhub.js
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
|
-
import { fetchJson, resolveImdbId } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
1
|
+
import { fetchJson, resolveImdbId, resolveTmdbKey } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://hdhub.thevolecitor.qzz.io';
|
|
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 config = btoa(JSON.stringify({ torbox: 'unset', qualities: '2160p,1080p,720p', sort: 'desc', catalogs: 'featured,popular' }));
|
|
15
|
+
const url = `${BASE_URL}/${config}/stream/${type}/${imdb}${isTv ? `:${s}:${e}` : ''}.json`;
|
|
16
|
+
|
|
17
|
+
const res = await fetchJson(url).catch(() => null);
|
|
18
|
+
if (!res || !Array.isArray(res.streams) || !res.streams.length) return null;
|
|
19
|
+
|
|
20
|
+
const validStreams = res.streams.filter(st => {
|
|
21
|
+
if (!st.url || !st.url.trim()) return false;
|
|
22
|
+
const lower = st.url.toLowerCase();
|
|
23
|
+
if (lower.includes('hubcloud') || lower.includes('pixeldrain.dev') || lower.endsWith('.zip')) return false;
|
|
24
|
+
return true;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
if (!validStreams.length) return null;
|
|
28
|
+
|
|
29
|
+
const allUrls = validStreams.map(st => ({
|
|
30
|
+
url: st.url,
|
|
31
|
+
server: `HDHub - ${st.name || 'Server'}`,
|
|
32
|
+
quality: 'Auto',
|
|
33
|
+
type: st.url.includes('.m3u8') ? 'hls' : 'mp4',
|
|
34
|
+
headers: st.behaviorHints?.proxyHeaders?.request || undefined,
|
|
35
|
+
skipProxy: st.behaviorHints?.notWebReady === false,
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
url: allUrls[0].url,
|
|
40
|
+
headers: allUrls[0].headers,
|
|
41
|
+
allUrls,
|
|
42
|
+
};
|
|
43
|
+
}
|
package/src/sources/hexa.js
CHANGED
|
@@ -1,54 +1,61 @@
|
|
|
1
|
-
import { fetchJson, fetchText } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
import { fetchJson, fetchText, getRandomHex } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const API_BASE = 'https://enc-dec.app/api';
|
|
4
|
+
const BASE_URL = 'https://hexa.su';
|
|
5
|
+
const TMDB_PROXY_BASE = 'https://theemoviedb.hexa.su';
|
|
6
|
+
|
|
7
|
+
export async function getStream(args) {
|
|
8
|
+
const { id, s, e } = args || {};
|
|
9
|
+
const isTv = s != null && e != null;
|
|
10
|
+
const key = getRandomHex(32);
|
|
11
|
+
|
|
12
|
+
const headers = {
|
|
13
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
|
|
14
|
+
Referer: `${BASE_URL}/`,
|
|
15
|
+
Accept: 'text/plain',
|
|
16
|
+
'X-Fingerprint-Lite': 'e9136c41504646444',
|
|
17
|
+
'X-Api-Key': key,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const encHexaRes = await fetchJson(`${API_BASE}/enc-hexa`);
|
|
21
|
+
if (!encHexaRes || encHexaRes.status !== 200) return null;
|
|
22
|
+
headers['X-Cap-Token'] = encHexaRes.result.token;
|
|
23
|
+
|
|
24
|
+
const url = isTv
|
|
25
|
+
? `${TMDB_PROXY_BASE}/api/tmdb/tv/${id}/season/${s}/episode/${e}/images`
|
|
26
|
+
: `${TMDB_PROXY_BASE}/api/tmdb/movie/${id}/images`;
|
|
27
|
+
|
|
28
|
+
const encrypted = await fetchText(url, { headers });
|
|
29
|
+
if (!encrypted) return null;
|
|
30
|
+
|
|
31
|
+
const decRes = await fetchJson(`${API_BASE}/dec-hexa`, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
body: JSON.stringify({ text: encrypted, key }),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (!decRes || decRes.status !== 200 || !decRes.result) return null;
|
|
38
|
+
|
|
39
|
+
const data = decRes.result;
|
|
40
|
+
const streamUrl = data.url || data.file || (Array.isArray(data.sources) ? data.sources[0]?.url : null);
|
|
41
|
+
if (!streamUrl) return null;
|
|
42
|
+
|
|
43
|
+
const streamHeaders = {
|
|
44
|
+
Referer: `${BASE_URL}/`,
|
|
45
|
+
Origin: BASE_URL,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const allUrls = [{
|
|
49
|
+
url: streamUrl,
|
|
50
|
+
server: 'Hexa',
|
|
51
|
+
quality: 'Auto',
|
|
52
|
+
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
53
|
+
headers: streamHeaders,
|
|
54
|
+
}];
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
url: streamUrl,
|
|
58
|
+
headers: streamHeaders,
|
|
59
|
+
allUrls,
|
|
60
|
+
};
|
|
54
61
|
}
|
package/src/sources/hyper.js
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
|
-
import { fetchJson } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
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
|
-
|
|
1
|
+
import { fetchJson } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://hyper.stravo.site';
|
|
4
|
+
const DEFAULT_ORIGIN = 'https://mzfi.me';
|
|
5
|
+
|
|
6
|
+
export async function getStream(args) {
|
|
7
|
+
const { id, s, e } = args || {};
|
|
8
|
+
const isTv = s != null && e != null;
|
|
9
|
+
|
|
10
|
+
const path = isTv
|
|
11
|
+
? `/local/stream/series/tmdb:${id}:${s}:${e}.json`
|
|
12
|
+
: `/local/stream/movie/tmdb:${id}.json`;
|
|
13
|
+
|
|
14
|
+
const url = `${BASE_URL}${path}`;
|
|
15
|
+
const res = await fetchJson(url).catch(() => null);
|
|
16
|
+
if (!res || !Array.isArray(res.streams)) return null;
|
|
17
|
+
|
|
18
|
+
const validStreams = res.streams.filter(item => {
|
|
19
|
+
if (!item.url || item.externalUrl) return false;
|
|
20
|
+
if (typeof item.title === 'string' && item.title.includes('🔒')) return false;
|
|
21
|
+
return true;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (!validStreams.length) return null;
|
|
25
|
+
|
|
26
|
+
const allUrls = validStreams.map(item => ({
|
|
27
|
+
url: item.url,
|
|
28
|
+
server: `Hyper - ${item.title?.replace(/[^\x20-\x7E]+/g, '').trim() || 'Server'}`,
|
|
29
|
+
quality: 'Auto',
|
|
30
|
+
type: item.url.includes('.m3u8') ? 'hls' : 'mp4',
|
|
31
|
+
headers: item.behaviorHints?.proxyHeaders?.request || {
|
|
32
|
+
Referer: `${DEFAULT_ORIGIN}/`,
|
|
33
|
+
Accept: '*/*',
|
|
34
|
+
},
|
|
35
|
+
skipProxy: item.behaviorHints?.notWebReady === false,
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
url: allUrls[0].url,
|
|
40
|
+
headers: allUrls[0].headers,
|
|
41
|
+
allUrls,
|
|
42
|
+
};
|
|
36
43
|
}
|
|
@@ -1,125 +1,118 @@
|
|
|
1
|
-
import { fetchJson, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const HLS_BASE =
|
|
5
|
-
const HEADERS = {
|
|
6
|
-
|
|
7
|
-
async function kaaSearch(query) {
|
|
8
|
-
const res = await fetchJson(`${
|
|
9
|
-
method:
|
|
10
|
-
headers: { ...HEADERS,
|
|
11
|
-
body: JSON.stringify({ page: 1, query }),
|
|
12
|
-
}).catch(() => null);
|
|
13
|
-
return Array.isArray(res?.result) ? res.result : [];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async function kaaShowInfo(showSlug) {
|
|
17
|
-
return fetchJson(`${
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function kaaEpisodePage(showSlug, ep) {
|
|
21
|
-
return fetchJson(`${
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function kaaAllEpisodes(showSlug) {
|
|
25
|
-
const first = await kaaEpisodePage(showSlug, 1);
|
|
26
|
-
if (!first) return [];
|
|
27
|
-
const pages = Array.isArray(first.pages) ? first.pages : [];
|
|
28
|
-
const all = Array.isArray(first.result) ? [...first.result] : [];
|
|
29
|
-
|
|
30
|
-
if (pages.length > 1) {
|
|
31
|
-
const rest = await Promise.all(
|
|
32
|
-
pages.slice(1).map(async
|
|
33
|
-
const startEp = pg.eps?.[0];
|
|
34
|
-
if (!startEp) return [];
|
|
35
|
-
const d = await kaaEpisodePage(showSlug, startEp);
|
|
36
|
-
return Array.isArray(d?.result) ? d.result : [];
|
|
37
|
-
})
|
|
38
|
-
);
|
|
39
|
-
for (const batch of rest) all.push(...batch);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return all;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function kaaEpisodeServers(showSlug, fullEpSlug) {
|
|
46
|
-
return fetchJson(`${
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function getStream(
|
|
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
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
} catch (err) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export async function getSources() {
|
|
124
|
-
return ['KickAssAnime'];
|
|
1
|
+
import { fetchJson, getTmdbMetadata, resolveTmdbKey, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://kaa.lt';
|
|
4
|
+
const HLS_BASE = 'https://hls.krussdomi.com/manifest';
|
|
5
|
+
const HEADERS = { 'User-Agent': USER_AGENT, Accept: 'application/json' };
|
|
6
|
+
|
|
7
|
+
async function kaaSearch(query) {
|
|
8
|
+
const res = await fetchJson(`${BASE_URL}/api/fsearch`, {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: { ...HEADERS, 'Content-Type': 'application/json' },
|
|
11
|
+
body: JSON.stringify({ page: 1, query }),
|
|
12
|
+
}).catch(() => null);
|
|
13
|
+
return Array.isArray(res?.result) ? res.result : [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function kaaShowInfo(showSlug) {
|
|
17
|
+
return fetchJson(`${BASE_URL}/api/show/${showSlug}`, { headers: HEADERS }).catch(() => null);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function kaaEpisodePage(showSlug, ep) {
|
|
21
|
+
return fetchJson(`${BASE_URL}/api/show/${showSlug}/episodes?ep=${ep}&lang=ja-JP`, { headers: HEADERS }).catch(() => null);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function kaaAllEpisodes(showSlug) {
|
|
25
|
+
const first = await kaaEpisodePage(showSlug, 1);
|
|
26
|
+
if (!first) return [];
|
|
27
|
+
const pages = Array.isArray(first.pages) ? first.pages : [];
|
|
28
|
+
const all = Array.isArray(first.result) ? [...first.result] : [];
|
|
29
|
+
|
|
30
|
+
if (pages.length > 1) {
|
|
31
|
+
const rest = await Promise.all(
|
|
32
|
+
pages.slice(1).map(async pg => {
|
|
33
|
+
const startEp = pg.eps?.[0];
|
|
34
|
+
if (!startEp) return [];
|
|
35
|
+
const d = await kaaEpisodePage(showSlug, startEp);
|
|
36
|
+
return Array.isArray(d?.result) ? d.result : [];
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
for (const batch of rest) all.push(...batch);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return all;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function kaaEpisodeServers(showSlug, fullEpSlug) {
|
|
46
|
+
return fetchJson(`${BASE_URL}/api/show/${showSlug}/episode/${fullEpSlug}`, { headers: HEADERS }).catch(() => null);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function getStream(args) {
|
|
50
|
+
const { id, s, e, sdk } = args || {};
|
|
51
|
+
const isTv = s != null && e != null;
|
|
52
|
+
const apiKey = resolveTmdbKey(args, sdk);
|
|
53
|
+
const epNum = e ? Number(e) : 1;
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const meta = await getTmdbMetadata(id, isTv, apiKey);
|
|
57
|
+
const titles = meta?.titles || [];
|
|
58
|
+
if (!titles.length) return null;
|
|
59
|
+
|
|
60
|
+
let showSlug = null;
|
|
61
|
+
for (const title of titles) {
|
|
62
|
+
const results = await kaaSearch(title);
|
|
63
|
+
if (results.length) {
|
|
64
|
+
showSlug = results[0].slug;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!showSlug) return null;
|
|
70
|
+
|
|
71
|
+
const showInfo = await kaaShowInfo(showSlug);
|
|
72
|
+
let fullEpSlug = null;
|
|
73
|
+
|
|
74
|
+
if (showInfo?.type === 'movie') {
|
|
75
|
+
const m = (showInfo.watch_uri || '').match(/\/(ep-(\d+)-([a-f0-9]+))$/i);
|
|
76
|
+
if (m) fullEpSlug = m[1];
|
|
77
|
+
} else {
|
|
78
|
+
const episodes = await kaaAllEpisodes(showSlug);
|
|
79
|
+
const epItem = episodes.find(item => item.episode_number === epNum);
|
|
80
|
+
if (epItem) fullEpSlug = `ep-${epItem.episode_number}-${epItem.slug}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!fullEpSlug) return null;
|
|
84
|
+
|
|
85
|
+
const episodeData = await kaaEpisodeServers(showSlug, fullEpSlug);
|
|
86
|
+
const servers = Array.isArray(episodeData?.servers) ? episodeData.servers : [];
|
|
87
|
+
|
|
88
|
+
const allUrls = [];
|
|
89
|
+
for (const srv of servers) {
|
|
90
|
+
if (!srv.src) continue;
|
|
91
|
+
const m = srv.src.match(/[?&]id=([^&]+)/);
|
|
92
|
+
if (m) {
|
|
93
|
+
allUrls.push({
|
|
94
|
+
url: `${HLS_BASE}/${m[1]}/master.m3u8`,
|
|
95
|
+
server: `KickAssAnime (${srv.name || 'Server'})`,
|
|
96
|
+
quality: 'Auto',
|
|
97
|
+
type: 'hls',
|
|
98
|
+
headers: HEADERS,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!allUrls.length) return null;
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
url: allUrls[0].url,
|
|
107
|
+
headers: allUrls[0].headers,
|
|
108
|
+
allUrls,
|
|
109
|
+
};
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function getSources(args) {
|
|
116
|
+
const stream = await getStream(args);
|
|
117
|
+
return stream?.allUrls ? [...new Set(stream.allUrls.map(u => u.server))] : ['KickAssAnime'];
|
|
125
118
|
}
|