@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.
Files changed (58) hide show
  1. package/package.json +3 -2
  2. package/src/config.js +99 -67
  3. package/src/health.js +60 -20
  4. package/src/sdk.d.ts +94 -121
  5. package/src/sdk.js +82 -78
  6. package/src/sources/111477.js +88 -100
  7. package/src/sources/123anime.js +120 -56
  8. package/src/sources/3eyedraven.js +82 -135
  9. package/src/sources/4movies.js +77 -0
  10. package/src/sources/aether.js +99 -0
  11. package/src/sources/castle.js +415 -0
  12. package/src/sources/cinecat.js +37 -18
  13. package/src/sources/cinemaarmy.js +179 -180
  14. package/src/sources/cinesrc.js +401 -397
  15. package/src/sources/cno.js +101 -94
  16. package/src/sources/dulo.js +134 -149
  17. package/src/sources/flaxmovies.js +114 -105
  18. package/src/sources/framextv.js +126 -0
  19. package/src/sources/frost.js +38 -29
  20. package/src/sources/fsonline.js +95 -47
  21. package/src/sources/hdhub.js +43 -36
  22. package/src/sources/hexa.js +60 -53
  23. package/src/sources/hyper.js +42 -35
  24. package/src/sources/kickassanime.js +117 -124
  25. package/src/sources/kisskh.js +114 -59
  26. package/src/sources/lmscript.js +72 -70
  27. package/src/sources/lookmovie.js +80 -79
  28. package/src/sources/meowtv.js +140 -0
  29. package/src/sources/movenerds.js +74 -124
  30. package/src/sources/movy.js +197 -209
  31. package/src/sources/net79.js +59 -55
  32. package/src/sources/peestream.js +126 -138
  33. package/src/sources/pengu.js +46 -49
  34. package/src/sources/pstream.js +73 -67
  35. package/src/sources/purstream.js +96 -104
  36. package/src/sources/rivestream.js +182 -176
  37. package/src/sources/rivo.js +58 -53
  38. package/src/sources/streamaggregator.js +114 -128
  39. package/src/sources/thugtv.js +70 -62
  40. package/src/sources/vidapi.js +122 -114
  41. package/src/sources/vidcore.js +14 -122
  42. package/src/sources/vidfast.js +14 -122
  43. package/src/sources/vidlink.js +78 -27
  44. package/src/sources/vidora.js +74 -42
  45. package/src/sources/vidup.js +14 -122
  46. package/src/sources/vidvault.js +133 -187
  47. package/src/sources/vidy.js +192 -187
  48. package/src/sources/vidzee.js +189 -183
  49. package/src/sources/vixsrc.js +123 -113
  50. package/src/sources/watchout.js +60 -46
  51. package/src/sources/xdownloader.js +127 -128
  52. package/src/sources/yapgrid.js +68 -62
  53. package/src/sources/yastream.js +35 -29
  54. package/src/subtitles.js +105 -122
  55. package/src/utils/helpers.js +586 -247
  56. package/src/sources/bcine.js +0 -202
  57. package/src/sources/cinezo.js +0 -55
  58. package/src/sources/vidrock.js +0 -145
@@ -1,36 +1,43 @@
1
- import { fetchJson, resolveImdbId } from '../utils/helpers.js';
2
-
3
- export async function getStream({ id, s, e, tmdbApiKey, sdk }) {
4
- const isTv = s != null && e != null;
5
- const type = isTv ? 'series' : 'movie';
6
- const imdb = await resolveImdbId(id, isTv, tmdbApiKey || sdk?.tmdbApiKey);
7
- if (!imdb) return null;
8
-
9
- const CONFIG = btoa(JSON.stringify({ "torbox": "unset", "qualities": "2160p,1080p,720p", "sort": "desc", "catalogs": "featured,popular" }));
10
- const url = `https://hdhub.thevolecitor.qzz.io/${CONFIG}/stream/${type}/${imdb}${isTv ? `:${s}:${e}` : ""}.json`;
11
-
12
- const res = await fetchJson(url).catch(() => null);
13
- if (!res || !Array.isArray(res.streams) || !res.streams.length) return null;
14
-
15
- const validStreams = res.streams.filter(st => {
16
- if (!st.url || !st.url.trim()) return false;
17
- const lower = st.url.toLowerCase();
18
- if (lower.includes('hubcloud') || lower.includes('pixeldrain.dev') || lower.endsWith('.zip')) return false;
19
- return true;
20
- });
21
-
22
- if (!validStreams.length) return null;
23
-
24
- const allUrls = validStreams.map(st => ({
25
- url: st.url,
26
- server: `HDHub - ${st.name || 'Server'}`,
27
- headers: st.behaviorHints?.proxyHeaders?.request || undefined,
28
- skipProxy: st.behaviorHints?.notWebReady === false
29
- }));
30
-
31
- return {
32
- url: allUrls[0].url,
33
- headers: allUrls[0].headers,
34
- allUrls
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
+ }
@@ -1,54 +1,61 @@
1
- import { fetchJson, fetchText } from '../utils/helpers.js';
2
-
3
- const API = "https://enc-dec.app/api";
4
-
5
- function getRandomHex(size = 32) {
6
- const array = new Uint8Array(size);
7
- crypto.getRandomValues(array);
8
- return Array.from(array).map(b => b.toString(16).padStart(2, '0')).join('');
9
- }
10
-
11
- export async function getStream({ id, s, e }) {
12
- const isTv = s != null && e != null;
13
- const key = getRandomHex(32);
14
-
15
- const headers = {
16
- "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",
17
- "Referer": "https://hexa.su/",
18
- "Accept": "text/plain",
19
- "X-Fingerprint-Lite": "e9136c41504646444",
20
- "X-Api-Key": key
21
- };
22
-
23
- const encHexaRes = await fetchJson(`${API}/enc-hexa`);
24
- if (!encHexaRes || encHexaRes.status !== 200) return null;
25
- headers["X-Cap-Token"] = encHexaRes.result.token;
26
-
27
- const url = isTv
28
- ? `https://theemoviedb.hexa.su/api/tmdb/tv/${id}/season/${s}/episode/${e}/images`
29
- : `https://theemoviedb.hexa.su/api/tmdb/movie/${id}/images`;
30
-
31
- const encrypted = await fetchText(url, { headers });
32
- if (!encrypted) return null;
33
-
34
- const decRes = await fetchJson(`${API}/dec-hexa`, {
35
- method: "POST",
36
- headers: { "Content-Type": "application/json" },
37
- body: JSON.stringify({ text: encrypted, key })
38
- });
39
-
40
- if (!decRes || decRes.status !== 200 || !decRes.result) return null;
41
-
42
- const data = decRes.result;
43
- const streamUrl = data.url || data.file || (Array.isArray(data.sources) ? data.sources[0]?.url : null);
44
-
45
- if (!streamUrl) return null;
46
-
47
- return {
48
- url: streamUrl,
49
- headers: {
50
- Referer: "https://hexa.su/",
51
- Origin: "https://hexa.su"
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
  }
@@ -1,36 +1,43 @@
1
- import { fetchJson } from '../utils/helpers.js';
2
-
3
- export async function getStream({ id, s, e }) {
4
- const isTv = s != null && e != null;
5
- const path = isTv
6
- ? `/local/stream/series/tmdb:${id}:${s}:${e}.json`
7
- : `/local/stream/movie/tmdb:${id}.json`;
8
-
9
- const url = `https://hyper.stravo.site${path}`;
10
- const res = await fetchJson(url);
11
- if (!res || !Array.isArray(res.streams)) return null;
12
-
13
- const validStreams = res.streams.filter(item => {
14
- if (!item.url || item.externalUrl) return false;
15
- if (typeof item.title === 'string' && item.title.includes('🔒')) return false;
16
- return true;
17
- });
18
-
19
- if (!validStreams.length) return null;
20
-
21
- const allUrls = validStreams.map(item => ({
22
- url: item.url,
23
- server: `Hyper - ${item.title?.replace(/[^\x20-\x7E]+/g, '').trim() || 'Server'}`,
24
- headers: item.behaviorHints?.proxyHeaders?.request || {
25
- Referer: 'https://mzfi.me/',
26
- Accept: '*/*'
27
- },
28
- skipProxy: item.behaviorHints?.notWebReady === false
29
- }));
30
-
31
- return {
32
- url: allUrls[0].url,
33
- headers: allUrls[0].headers,
34
- allUrls
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 BASE = "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}/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}/api/show/${showSlug}`, { headers: HEADERS }).catch(() => null);
18
- }
19
-
20
- async function kaaEpisodePage(showSlug, ep) {
21
- return fetchJson(`${BASE}/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}/api/show/${showSlug}/episode/${fullEpSlug}`, { headers: HEADERS }).catch(() => null);
47
- }
48
-
49
- export async function getStream({ id, s, e, tmdbApiKey, sdk }) {
50
- try {
51
- const apiKey = tmdbApiKey || sdk?.tmdbApiKey || process.env.TMDB_API_KEY || '45dbdd5e714da212424bda0336167447';
52
- const isTv = !!s;
53
- const mediaType = isTv ? 'tv' : 'movie';
54
- const epNum = e ? Number(e) : 1;
55
-
56
- let titles = [];
57
- try {
58
- const tmdbRes = await fetchJson(`https://api.themoviedb.org/3/${mediaType}/${id}?api_key=${apiKey}&append_to_response=alternative_titles`);
59
- if (tmdbRes) {
60
- const primary = tmdbRes.title || tmdbRes.name;
61
- const original = tmdbRes.original_title || tmdbRes.original_name;
62
- if (primary) titles.push(primary);
63
- if (original && !titles.includes(original)) titles.push(original);
64
-
65
- const alts = tmdbRes.alternative_titles?.titles || tmdbRes.alternative_titles?.results || [];
66
- for (const alt of alts) {
67
- const candidate = alt.title || alt.name;
68
- if (candidate && !titles.includes(candidate)) {
69
- titles.push(candidate);
70
- }
71
- }
72
- }
73
- } catch { }
74
-
75
- if (!titles.length) return null;
76
-
77
- let showSlug = null;
78
- for (const title of titles) {
79
- const results = await kaaSearch(title);
80
- if (results.length) {
81
- showSlug = results[0].slug;
82
- break;
83
- }
84
- }
85
-
86
- if (!showSlug) return null;
87
-
88
- const showInfo = await kaaShowInfo(showSlug);
89
- let fullEpSlug = null;
90
-
91
- if (showInfo?.type === "movie") {
92
- const m = (showInfo.watch_uri || "").match(/\/(ep-(\d+)-([a-f0-9]+))$/i);
93
- if (m) fullEpSlug = m[1];
94
- } else {
95
- const episodes = await kaaAllEpisodes(showSlug);
96
- const epItem = episodes.find((item) => item.episode_number === epNum);
97
- if (epItem) fullEpSlug = `ep-${epItem.episode_number}-${epItem.slug}`;
98
- }
99
-
100
- if (!fullEpSlug) return null;
101
-
102
- const episodeData = await kaaEpisodeServers(showSlug, fullEpSlug);
103
- const servers = Array.isArray(episodeData?.servers) ? episodeData.servers : [];
104
-
105
- const urls = [];
106
- for (const srv of servers) {
107
- if (!srv.src) continue;
108
- const m = srv.src.match(/[?&]id=([^&]+)/);
109
- if (m) {
110
- urls.push({
111
- url: `${HLS_BASE}/${m[1]}/master.m3u8`,
112
- server: `KickAssAnime (${srv.name || 'Server'})`,
113
- });
114
- }
115
- }
116
-
117
- return urls.length ? { allUrls: urls } : null;
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
  }