@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,181 +1,180 @@
1
- import crypto from "crypto";
2
- import { Session, ClientIdentifier, initTLS, destroyTLS } from "node-tls-client";
3
-
4
- const BASE_URL = "https://cinema.army";
5
- const API_BASE = "https://cinema.army/api";
6
-
7
- const XOR_KEY = "f16a6b92fcd6eed3e9476297f893f2505c32f79bc6efef9b6c95496aa5914548";
8
- const HMAC_KEY = "a2cfc9eaa2a3690b5d4f6b5f958dbdeae52a097283d375bd253ee7c7062524f5";
9
-
10
- const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
11
-
12
- const SERVERS = [
13
- { key: "cookiebakers", method: "POST", label: "CookieBakers" },
14
- { key: "tcloud", method: "GET", label: "TCloud" },
15
- { key: "ipcloud", method: "GET", label: "IPcloud" },
16
- { key: "dcloud", method: "GET", label: "Dcloud" },
17
- ];
18
-
19
- let tlsInitialized = false;
20
- let session = null;
21
-
22
- async function ensureSession() {
23
- if (!tlsInitialized) {
24
- await initTLS();
25
- tlsInitialized = true;
26
- }
27
- if (!session) {
28
- session = new Session({
29
- clientIdentifier: ClientIdentifier.chrome_131,
30
- timeout: 15000,
31
- insecureSkipVerify: false,
32
- });
33
- }
34
- return session;
35
- }
36
-
37
- function getHeaders(token, id, isTv, s, e) {
38
- const referer = isTv
39
- ? `${BASE_URL}/watch?id=${id}&type=tv&season=${s}&episode=${e}`
40
- : `${BASE_URL}/watch?id=${id}&type=movie`;
41
-
42
- return {
43
- "User-Agent": UA,
44
- "Accept": "application/json",
45
- "Accept-Language": "en-US,en;q=0.9",
46
- "Accept-Encoding": "gzip, deflate, br",
47
- "Cache-Control": "no-cache",
48
- "Pragma": "no-cache",
49
- "Referer": referer,
50
- "Origin": BASE_URL,
51
- "Sec-Ch-Ua": '"Chromium";v="131", "Not_A Brand";v="24"',
52
- "Sec-Ch-Ua-Mobile": "?0",
53
- "Sec-Ch-Ua-Platform": '"Windows"',
54
- "Sec-Fetch-Dest": "empty",
55
- "Sec-Fetch-Mode": "cors",
56
- "Sec-Fetch-Site": "same-origin",
57
- "Priority": "u=1, i",
58
- "X-Stream-Token": token,
59
- };
60
- }
61
-
62
- function generateToken(id) {
63
- try {
64
- const minute = Math.floor(Date.now() / 1000 / 60);
65
- return crypto
66
- .createHmac("sha256", HMAC_KEY)
67
- .update(`${id}:${minute}`)
68
- .digest("hex");
69
- } catch {
70
- return "";
71
- }
72
- }
73
-
74
- function decryptStreamUrl(encoded) {
75
- if (!encoded) return "";
76
- if (encoded.startsWith("http://") || encoded.startsWith("https://")) return encoded;
77
- try {
78
- const decoded = Buffer.from(encoded, "base64").toString("binary");
79
- let out = "";
80
- for (let i = 0; i < decoded.length; i++) {
81
- out += String.fromCharCode(
82
- decoded.charCodeAt(i) ^ XOR_KEY.charCodeAt(i % XOR_KEY.length)
83
- );
84
- }
85
- return out;
86
- } catch {
87
- return encoded;
88
- }
89
- }
90
-
91
- export async function getStream(args) {
92
- const { id, s = null, e = null } = args;
93
- const isTv = s != null && e != null;
94
-
95
- const token = generateToken(id);
96
- const headers = getHeaders(token, id, isTv, s, e);
97
-
98
- const sess = await ensureSession();
99
-
100
- const requests = SERVERS.map(server => {
101
- const path = isTv
102
- ? `/${server.key}/tv/${id}/${s}/${e}`
103
- : `/${server.key}/movie/${id}`;
104
- return { url: `${API_BASE}${path}`, server };
105
- });
106
-
107
- const results = await Promise.allSettled(
108
- requests.map(async ({ url, server }) => {
109
- try {
110
- const res = server.method === "POST"
111
- ? await sess.post(url, { headers })
112
- : await sess.get(url, { headers });
113
-
114
- if (res.status !== 200) {
115
- if (process.env.DEBUG_CAUSE) {
116
- console.error(`[CinemaArmy ${server.key}] HTTP ${res.status}`);
117
- }
118
- return null;
119
- }
120
-
121
- const text = await res.text();
122
- let data;
123
- try {
124
- data = JSON.parse(text);
125
- } catch {
126
- return null;
127
- }
128
-
129
- const encrypted = data?.stream?.url;
130
- if (!encrypted) return null;
131
-
132
- const streamUrl = decryptStreamUrl(encrypted);
133
- if (!streamUrl || !/^https?:\/\//.test(streamUrl)) return null;
134
-
135
- return {
136
- url: streamUrl,
137
- headers: {
138
- "User-Agent": UA,
139
- Referer: `${BASE_URL}/`,
140
- Origin: BASE_URL,
141
- },
142
- server: `CinemaArmy (${server.label})`,
143
- quality: "1080p",
144
- type: streamUrl.includes(".m3u8") ? "hls" : "mp4",
145
- };
146
- } catch (err) {
147
- if (process.env.DEBUG_CAUSE) {
148
- console.error(`[CinemaArmy ${server.key}] ${err.message}`);
149
- if (err.cause) {
150
- console.error(` cause.code: ${err.cause.code || "n/a"}`);
151
- console.error(` cause.message: ${err.cause.message || err.cause}`);
152
- }
153
- }
154
- return null;
155
- }
156
- })
157
- );
158
-
159
- const allUrls = results
160
- .filter(r => r.status === "fulfilled" && r.value)
161
- .map(r => r.value);
162
-
163
- if (!allUrls.length) return null;
164
-
165
- return { allUrls };
166
- }
167
-
168
- export async function cleanup() {
169
- if (session) {
170
- try {
171
- await session.close();
172
- } catch { }
173
- session = null;
174
- }
175
- if (tlsInitialized) {
176
- try {
177
- await destroyTLS();
178
- } catch { }
179
- tlsInitialized = false;
180
- }
1
+ import crypto from 'node:crypto';
2
+ import { ClientIdentifier, destroyTLS, initTLS, Session } from 'node-tls-client';
3
+
4
+ const BASE_URL = 'https://cinema.army';
5
+ const API_BASE = `${BASE_URL}/api`;
6
+ const HMAC_KEY = 'a2cfc9eaa2a3690b5d4f6b5f958dbdeae52a097283d375bd253ee7c7062524f5';
7
+ const XOR_KEY = 'f16a6b92fcd6eed3e9476297f893f2505c32f79bc6efef9b6c95496aa5914548';
8
+ const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';
9
+
10
+ const SERVERS = [
11
+ { key: 'cookiebakers', label: 'CookieBakers', method: 'POST' },
12
+ { key: 'tcloud', label: 'TCloud', method: 'POST' },
13
+ { key: 'ipcloud', label: 'IPCloud', method: 'POST' },
14
+ { key: 'dcloud', label: 'DCloud', method: 'POST' },
15
+ { key: 'tidb', label: 'TIDB', method: 'POST' },
16
+ ];
17
+
18
+ let tlsInitialized = false;
19
+ let session = null;
20
+
21
+ async function ensureSession() {
22
+ if (!tlsInitialized) {
23
+ await initTLS();
24
+ tlsInitialized = true;
25
+ }
26
+ if (!session) {
27
+ session = new Session({
28
+ clientIdentifier: ClientIdentifier.chrome_131,
29
+ timeout: 15000,
30
+ insecureSkipVerify: false,
31
+ });
32
+ }
33
+ return session;
34
+ }
35
+
36
+ function getHeaders(token, id, isTv, s, e) {
37
+ const referer = isTv
38
+ ? `${BASE_URL}/watch?id=${id}&type=tv&season=${s}&episode=${e}`
39
+ : `${BASE_URL}/watch?id=${id}&type=movie`;
40
+
41
+ return {
42
+ 'User-Agent': UA,
43
+ Accept: 'application/json',
44
+ 'Accept-Language': 'en-US,en;q=0.9',
45
+ 'Accept-Encoding': 'gzip, deflate, br',
46
+ 'Cache-Control': 'no-cache',
47
+ Pragma: 'no-cache',
48
+ Referer: referer,
49
+ Origin: BASE_URL,
50
+ 'Sec-Ch-Ua': '"Chromium";v="131", "Not_A Brand";v="24"',
51
+ 'Sec-Ch-Ua-Mobile': '?0',
52
+ 'Sec-Ch-Ua-Platform': '"Windows"',
53
+ 'Sec-Fetch-Dest': 'empty',
54
+ 'Sec-Fetch-Mode': 'cors',
55
+ 'Sec-Fetch-Site': 'same-origin',
56
+ Priority: 'u=1, i',
57
+ 'X-Stream-Token': token,
58
+ };
59
+ }
60
+
61
+ function generateToken(id) {
62
+ try {
63
+ const minute = Math.floor(Date.now() / 1000 / 60);
64
+ return crypto
65
+ .createHmac('sha256', HMAC_KEY)
66
+ .update(`${id}:${minute}`)
67
+ .digest('hex');
68
+ } catch {
69
+ return '';
70
+ }
71
+ }
72
+
73
+ function decryptStreamUrl(encoded) {
74
+ if (!encoded) return '';
75
+ if (encoded.startsWith('http://') || encoded.startsWith('https://')) return encoded;
76
+ try {
77
+ const decoded = Buffer.from(encoded, 'base64').toString('binary');
78
+ let out = '';
79
+ for (let i = 0; i < decoded.length; i++) {
80
+ out += String.fromCharCode(
81
+ decoded.charCodeAt(i) ^ XOR_KEY.charCodeAt(i % XOR_KEY.length)
82
+ );
83
+ }
84
+ return out;
85
+ } catch {
86
+ return encoded;
87
+ }
88
+ }
89
+
90
+ export async function getStream(args) {
91
+ const { id, s, e } = args || {};
92
+ const isTv = s != null && e != null;
93
+
94
+ const token = generateToken(id);
95
+ const headers = getHeaders(token, id, isTv, s, e);
96
+
97
+ const sess = await ensureSession();
98
+
99
+ const requests = SERVERS.map(server => {
100
+ const path = isTv
101
+ ? `/${server.key}/tv/${id}/${s}/${e}`
102
+ : `/${server.key}/movie/${id}`;
103
+ return { url: `${API_BASE}${path}`, server };
104
+ });
105
+
106
+ const results = await Promise.allSettled(
107
+ requests.map(async ({ url, server }) => {
108
+ try {
109
+ const res = server.method === 'POST'
110
+ ? await sess.post(url, { headers, body: '' })
111
+ : await sess.get(url, { headers });
112
+
113
+ if (res?.status !== 200) return null;
114
+
115
+ const rawBody = typeof res.text === 'function' ? await res.text() : res.body;
116
+
117
+ let data;
118
+ try {
119
+ data = typeof rawBody === 'object' && rawBody !== null ? rawBody : JSON.parse(rawBody);
120
+ } catch (err) {
121
+ return null;
122
+ }
123
+
124
+ const encrypted = data?.stream?.url;
125
+ if (!encrypted) {
126
+ return null;
127
+ }
128
+
129
+ const streamUrl = decryptStreamUrl(encrypted);
130
+
131
+ if (!streamUrl || !/^https?:\/\//.test(streamUrl)) {
132
+ return null;
133
+ }
134
+
135
+ return {
136
+ url: streamUrl,
137
+ headers: {
138
+ 'User-Agent': UA,
139
+ Referer: `${BASE_URL}/`,
140
+ Origin: BASE_URL,
141
+ },
142
+ server: `CinemaArmy (${server.label})`,
143
+ quality: '1080p',
144
+ type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
145
+ };
146
+ } catch (err) {
147
+ return null;
148
+ }
149
+ })
150
+ );
151
+
152
+ const allUrls = results
153
+ .filter(r => r.status === 'fulfilled' && r.value)
154
+ .map(r => r.value);
155
+
156
+ if (!allUrls.length) {
157
+ return null;
158
+ }
159
+
160
+ return {
161
+ url: allUrls[0].url,
162
+ headers: allUrls[0].headers,
163
+ allUrls,
164
+ };
165
+ }
166
+
167
+ export async function cleanup() {
168
+ if (session) {
169
+ try {
170
+ await session.close();
171
+ } catch { }
172
+ session = null;
173
+ }
174
+ if (tlsInitialized) {
175
+ try {
176
+ await destroyTLS();
177
+ } catch { }
178
+ tlsInitialized = false;
179
+ }
181
180
  }