@vyla-entertainment/sdk 1.0.0 → 1.2.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/.env.example +1 -0
- package/.github/workflows/publish.yml +38 -0
- package/.gitlab-ci.yml +22 -0
- package/LICENSE +0 -0
- package/README.md +13 -26
- package/package.json +5 -3
- package/src/config.js +63 -77
- package/src/downloads/downloads.js +8 -4
- package/src/downloads/sources/trendimovies.js +0 -0
- package/src/health.js +0 -0
- package/src/sdk.d.ts +123 -0
- package/src/sdk.js +0 -0
- package/src/sources/123anime.js +0 -0
- package/src/sources/anihq.js +14 -2
- package/src/sources/anineko.js +122 -15
- package/src/sources/anipm.js +0 -0
- package/src/sources/cinejoy.js +210 -0
- package/src/sources/flaxmovies.js +114 -10
- package/src/sources/frame.js +88 -0
- package/src/sources/fsharetv.js +0 -0
- package/src/sources/fsonic.js +2 -2
- package/src/sources/fsonline.js +2 -2
- package/src/sources/hexa.js +0 -0
- package/src/sources/kisskh.js +0 -0
- package/src/sources/lmscript.js +43 -0
- package/src/sources/lookmovie.js +0 -0
- package/src/sources/mapple.js +40 -4
- package/src/sources/meowtv.js +1 -9
- package/src/sources/peestream.js +122 -0
- package/src/sources/pengu.js +0 -0
- package/src/sources/purstream.js +0 -0
- package/src/sources/vidapi.js +0 -0
- package/src/sources/vidcore.js +0 -0
- package/src/sources/videasy.js +6 -12
- package/src/sources/vidfast.js +0 -0
- package/src/sources/vidlink.js +0 -0
- package/src/sources/vidnest.js +0 -0
- package/src/sources/vidrift.js +0 -0
- package/src/sources/vidrock.js +0 -0
- package/src/sources/vidsync.js +0 -0
- package/src/sources/vidup.js +0 -0
- package/src/sources/vidvault.js +114 -0
- package/src/sources/vidzee.js +73 -87
- package/src/sources/vixsrc.js +28 -14
- package/src/sources/xpass.js +0 -0
- package/src/subtitles.js +0 -0
- package/src/utils/helpers.js +56 -20
- package/src/sources/1embed.js +0 -92
- package/src/sources/goated.js +0 -262
- package/src/sources/nebula.js +0 -62
- package/src/sources/nekowatch.js +0 -57
- package/src/sources/opstream.js +0 -123
- package/src/sources/peachify.js +0 -78
package/src/sources/nekowatch.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { fetchJson, fetchText, getTmdbInfo, tmdbToAnilist } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const BASE_URL = "https://nekowatch.xyz";
|
|
4
|
-
const ANIME_JS_URL = `${BASE_URL}/js/anime.js?v=v263_fast_player_start`;
|
|
5
|
-
const FALLBACK_ORDER = ['kiwi', 'ally', 'bee', 'arc', 'anikoto', 'jet', 'bonk', 'moo', 'hop', 'pulsar', 'pahe'];
|
|
6
|
-
|
|
7
|
-
let providerOrderCache = null, providerOrderTs = 0;
|
|
8
|
-
|
|
9
|
-
async function getProviderOrder() {
|
|
10
|
-
const now = Date.now();
|
|
11
|
-
if (providerOrderCache && now - providerOrderTs < 1800000) return providerOrderCache;
|
|
12
|
-
try {
|
|
13
|
-
const js = await fetchText(ANIME_JS_URL, { signal: AbortSignal.timeout(6000) });
|
|
14
|
-
const match = js.match(/PROVIDER_ORDER\s*=\s*\[([\s\S]*?)\]/);
|
|
15
|
-
if (match) {
|
|
16
|
-
const order = [...match[1].matchAll(/['"]([a-z0-9_]+)['"]/gi)].map(m => m[1]);
|
|
17
|
-
if (order.length) { providerOrderCache = order; providerOrderTs = now; return order; }
|
|
18
|
-
}
|
|
19
|
-
} catch { }
|
|
20
|
-
return providerOrderCache || FALLBACK_ORDER;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function getStream({ id, s, e, audio }) {
|
|
24
|
-
try {
|
|
25
|
-
const info = await getTmdbInfo(id, s ? 'tv' : 'movie', s);
|
|
26
|
-
if (!info || !info.isAnime) return null;
|
|
27
|
-
const anilistId = await tmdbToAnilist(id, s ? 'tv' : 'movie', s, info.titles, info.year);
|
|
28
|
-
if (!anilistId) return null;
|
|
29
|
-
const ep = e || 1;
|
|
30
|
-
const audiosToTry = audio === "all" ? ["sub", "dub"] : (audio === "dub" ? ["dub", "sub"] : ["sub", "dub"]);
|
|
31
|
-
const providerOrder = await getProviderOrder();
|
|
32
|
-
for (const aud of audiosToTry) {
|
|
33
|
-
const results = await Promise.allSettled(providerOrder.map(p => fetchJson(`${BASE_URL}/api/anime/watch/${p}/${anilistId}/${aud}/${p}-${ep}`, { signal: AbortSignal.timeout(8000) })));
|
|
34
|
-
const allUrls = [], seenActual = new Set();
|
|
35
|
-
for (const r of results) {
|
|
36
|
-
if (r.status !== 'fulfilled' || !r.value) continue;
|
|
37
|
-
const data = r.value;
|
|
38
|
-
let streams = [], actual = data.attempted?.actualProvider || data.provider;
|
|
39
|
-
if (Array.isArray(data.streams)) streams = data.streams;
|
|
40
|
-
else {
|
|
41
|
-
for (const key of Object.keys(data)) if (data[key] && Array.isArray(data[key].streams)) { streams.push(...data[key].streams); if (!actual) actual = data[key].provider || key; }
|
|
42
|
-
}
|
|
43
|
-
if (!streams.length) continue;
|
|
44
|
-
if (actual) { if (seenActual.has(actual)) continue; seenActual.add(actual); }
|
|
45
|
-
const valid = streams.filter(st => st.type === "hls" && st.url).sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
46
|
-
for (const st of valid) allUrls.push({ url: st.url, type: "hls", audio: aud, server: st.server ? `NekoWatch-${st.server}` : "NekoWatch", headers: st.referer ? { Referer: st.referer } : undefined, skipProxy: /\.workers\.dev(\/|$)/i.test(st.url) });
|
|
47
|
-
}
|
|
48
|
-
if (allUrls.length) return { allUrls };
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
} catch { return null; }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function getSources(args) {
|
|
55
|
-
const stream = await getStream(args);
|
|
56
|
-
return stream?.allUrls ? [...new Set(stream.allUrls.map(u => u.server))] : [];
|
|
57
|
-
}
|
package/src/sources/opstream.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { getTmdbInfo, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const BASE_URL = 'https://opstream.fun';
|
|
4
|
-
const API_BASE = `${BASE_URL}/api/resolve`;
|
|
5
|
-
|
|
6
|
-
const API_HEADERS = {
|
|
7
|
-
'User-Agent': USER_AGENT,
|
|
8
|
-
'Accept': 'application/x-ndjson; charset=utf-8',
|
|
9
|
-
'Referer': `${BASE_URL}/`,
|
|
10
|
-
'Origin': BASE_URL,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const STREAM_HEADERS = {
|
|
14
|
-
'User-Agent': USER_AGENT,
|
|
15
|
-
'Referer': `${BASE_URL}/`,
|
|
16
|
-
'Origin': BASE_URL,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export async function getStream({ id, s, e }) {
|
|
20
|
-
try {
|
|
21
|
-
const isTv = s != null && e != null;
|
|
22
|
-
const info = await getTmdbInfo(id, isTv ? 'tv' : 'movie');
|
|
23
|
-
|
|
24
|
-
if (!info?.titles?.length || !info.imdbId) return null;
|
|
25
|
-
|
|
26
|
-
const params = new URLSearchParams({
|
|
27
|
-
type: isTv ? 'tv' : 'movie',
|
|
28
|
-
tmdbId: id,
|
|
29
|
-
title: info.titles[0],
|
|
30
|
-
year: info.year || '',
|
|
31
|
-
imdbId: info.imdbId,
|
|
32
|
-
progress: '1'
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (isTv) {
|
|
36
|
-
params.append('season', s);
|
|
37
|
-
params.append('episode', e);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const res = await fetch(`${API_BASE}?${params}`, {
|
|
41
|
-
headers: API_HEADERS,
|
|
42
|
-
signal: AbortSignal.timeout(15000)
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
if (!res.ok) return null;
|
|
46
|
-
|
|
47
|
-
const text = await res.text();
|
|
48
|
-
const lines = text.split('\n');
|
|
49
|
-
|
|
50
|
-
let streamData = null;
|
|
51
|
-
for (const line of lines) {
|
|
52
|
-
const trimmed = line.trim();
|
|
53
|
-
if (!trimmed) continue;
|
|
54
|
-
try {
|
|
55
|
-
const json = JSON.parse(trimmed);
|
|
56
|
-
if (json.t === 'done' && json.data) {
|
|
57
|
-
streamData = json.data;
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
} catch { continue; }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!streamData) return null;
|
|
64
|
-
|
|
65
|
-
const subtitles = (streamData.captions || []).map(c => ({
|
|
66
|
-
url: c.url.startsWith('http') ? c.url : `${BASE_URL}${c.url}`,
|
|
67
|
-
lang: c.label || 'Unknown'
|
|
68
|
-
}));
|
|
69
|
-
|
|
70
|
-
const allUrls = [];
|
|
71
|
-
|
|
72
|
-
if (streamData.qualities && streamData.qualities.length > 0) {
|
|
73
|
-
for (const q of streamData.qualities) {
|
|
74
|
-
let finalUrl = q.url;
|
|
75
|
-
if (!finalUrl.startsWith('http')) {
|
|
76
|
-
finalUrl = `${BASE_URL}${finalUrl}`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const isDash = finalUrl.includes('.mpd');
|
|
80
|
-
const isHls = finalUrl.includes('.m3u8');
|
|
81
|
-
|
|
82
|
-
allUrls.push({
|
|
83
|
-
url: finalUrl,
|
|
84
|
-
server: `OpStream - ${q.label}`,
|
|
85
|
-
type: isDash ? 'dash' : (isHls ? 'hls' : 'mp4'),
|
|
86
|
-
headers: STREAM_HEADERS,
|
|
87
|
-
subtitles,
|
|
88
|
-
skipProxy: true
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
} else if (streamData.url) {
|
|
92
|
-
let finalUrl = streamData.url;
|
|
93
|
-
if (finalUrl.includes('?u=')) {
|
|
94
|
-
try {
|
|
95
|
-
const uParam = new URL(finalUrl, BASE_URL).searchParams.get('u');
|
|
96
|
-
if (uParam) finalUrl = Buffer.from(uParam, 'base64').toString('utf8');
|
|
97
|
-
} catch {}
|
|
98
|
-
} else if (!finalUrl.startsWith('http')) {
|
|
99
|
-
finalUrl = `${BASE_URL}${finalUrl}`;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const isDash = streamData.kind === 'dash' || finalUrl.includes('.mpd');
|
|
103
|
-
const isHls = streamData.kind === 'hls' || finalUrl.includes('.m3u8');
|
|
104
|
-
|
|
105
|
-
allUrls.push({
|
|
106
|
-
url: finalUrl,
|
|
107
|
-
server: 'OpStream',
|
|
108
|
-
type: isDash ? 'dash' : (isHls ? 'hls' : 'mp4'),
|
|
109
|
-
headers: STREAM_HEADERS,
|
|
110
|
-
subtitles,
|
|
111
|
-
skipProxy: true
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (allUrls.length === 0) return null;
|
|
116
|
-
|
|
117
|
-
return { allUrls };
|
|
118
|
-
} catch { return null; }
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export async function getSources() {
|
|
122
|
-
return ['OpStream'];
|
|
123
|
-
}
|
package/src/sources/peachify.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { fetchJson, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const DEC_API = "https://enc-dec.app/api/dec-peachify";
|
|
4
|
-
const ORIGIN = "https://peachify.top";
|
|
5
|
-
const HEADERS = { "User-Agent": USER_AGENT, "Origin": ORIGIN, "Referer": `${ORIGIN}/` };
|
|
6
|
-
|
|
7
|
-
const SERVERS = [
|
|
8
|
-
{ label: "Wolf", path: "air", api: "https://usa.eat-peach.sbs" },
|
|
9
|
-
{ label: "Spider", path: "holly", api: "https://usa.eat-peach.sbs" },
|
|
10
|
-
{ label: "Iron", path: "moviebox", api: "https://uwu.eat-peach.sbs" },
|
|
11
|
-
{ label: "Multi", path: "multi", api: "https://usa.eat-peach.sbs" },
|
|
12
|
-
{ label: "Dark", path: "net", api: "https://uwu.eat-peach.sbs" },
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
export async function getStream({ id, s, e, server }) {
|
|
16
|
-
try {
|
|
17
|
-
const isTv = s != null && e != null;
|
|
18
|
-
const segment = isTv ? `tv/${id}/${s}/${e}` : `movie/${id}`;
|
|
19
|
-
|
|
20
|
-
let targets = SERVERS;
|
|
21
|
-
if (server && server !== 'all') {
|
|
22
|
-
const cleanName = server.replace('Peachify - ', '');
|
|
23
|
-
targets = SERVERS.filter(srv => srv.label === cleanName);
|
|
24
|
-
if (!targets.length) targets = SERVERS;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const settled = await Promise.allSettled(targets.map(async srv => {
|
|
28
|
-
const url = `${srv.api}/${srv.path}/${segment}`;
|
|
29
|
-
const rawData = await fetchJson(url, { headers: HEADERS, signal: AbortSignal.timeout(10000) });
|
|
30
|
-
|
|
31
|
-
if (!rawData?.data) throw new Error();
|
|
32
|
-
|
|
33
|
-
const decJson = await fetchJson(DEC_API, {
|
|
34
|
-
method: 'POST',
|
|
35
|
-
headers: { 'Content-Type': 'application/json' },
|
|
36
|
-
body: JSON.stringify({ text: rawData.data }),
|
|
37
|
-
signal: AbortSignal.timeout(10000)
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (decJson.status !== 200 || !decJson.result) throw new Error();
|
|
41
|
-
const res = decJson.result;
|
|
42
|
-
|
|
43
|
-
const sources = Array.isArray(res) ? res : (res.sources || [res]);
|
|
44
|
-
const subs = res.subtitles || [];
|
|
45
|
-
|
|
46
|
-
return sources.map(source => {
|
|
47
|
-
const streamUrl = source.url || source.file || source.link;
|
|
48
|
-
if (!streamUrl) return null;
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
url: streamUrl,
|
|
52
|
-
server: `Peachify - ${srv.label}`,
|
|
53
|
-
quality: source.quality || "Auto",
|
|
54
|
-
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
55
|
-
headers: { ...HEADERS, "Origin": ORIGIN },
|
|
56
|
-
subtitles: subs.map(sub => ({
|
|
57
|
-
url: sub.url || sub.file,
|
|
58
|
-
lang: sub.language || sub.lang || sub.label || 'Unknown'
|
|
59
|
-
})),
|
|
60
|
-
skipProxy: false,
|
|
61
|
-
skipVerify: true,
|
|
62
|
-
skipHlsCheck: true
|
|
63
|
-
};
|
|
64
|
-
}).filter(Boolean);
|
|
65
|
-
}));
|
|
66
|
-
|
|
67
|
-
const allUrls = [];
|
|
68
|
-
for (const r of settled) {
|
|
69
|
-
if (r.status === 'fulfilled' && r.value) allUrls.push(...r.value);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return allUrls.length ? { allUrls } : null;
|
|
73
|
-
} catch { return null; }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export async function getSources() {
|
|
77
|
-
return SERVERS.map(s => `Peachify - ${s.label}`);
|
|
78
|
-
}
|