@vyla-entertainment/sdk 1.20.0 → 1.21.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 +10 -85
- 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/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/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/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/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/vidora.js +0 -62
- package/src/sources/vidrock.js +0 -145
package/src/sources/movy.js
CHANGED
|
@@ -1,210 +1,198 @@
|
|
|
1
|
-
import { fetchJson, fetchText,
|
|
2
|
-
|
|
3
|
-
const K = [
|
|
4
|
-
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
|
5
|
-
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
6
|
-
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
7
|
-
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
|
|
8
|
-
];
|
|
9
|
-
const MAGIC = [109, 118, 109, 49];
|
|
10
|
-
|
|
11
|
-
const isEven = e => ((e * (e + 1)) & 1) === 0;
|
|
12
|
-
|
|
13
|
-
function scramble(e) {
|
|
14
|
-
e >>>= 0;
|
|
15
|
-
e ^= e >>> 16;
|
|
16
|
-
e = Math.imul(e, 0x85ebca6b) >>> 0;
|
|
17
|
-
e ^= e >>> 13;
|
|
18
|
-
e = Math.imul(e, 0xc2b2ae35) >>> 0;
|
|
19
|
-
return (e ^ (e >>> 16)) >>> 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function rotl(e, a) {
|
|
23
|
-
e >>>= 0;
|
|
24
|
-
a &= 31;
|
|
25
|
-
return a === 0 ? e >>> 0 : ((e << a) | (e >>> (32 - a))) >>> 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function initCipherState(keyStr, seedStr) {
|
|
29
|
-
let keyLen = keyStr.length;
|
|
30
|
-
if (((keyLen * (keyLen + 1)) & 1) === 1) {
|
|
31
|
-
const S = new Array(256);
|
|
32
|
-
for (let i = 0; i < 256; i++) S[i] = i;
|
|
33
|
-
let j = 0;
|
|
34
|
-
for (let i = 0; i < 256; i++) {
|
|
35
|
-
j = (j + S[i] + keyStr.charCodeAt(i % keyStr.length)) & 255;
|
|
36
|
-
const tmp = S[i];
|
|
37
|
-
S[i] = S[j];
|
|
38
|
-
S[j] = tmp;
|
|
39
|
-
}
|
|
40
|
-
let acc = 0x67452301;
|
|
41
|
-
for (let i = 0; i < keyStr.length; i++) {
|
|
42
|
-
acc = rotl((acc ^ Math.imul(keyStr.charCodeAt(i), K[15 & i])) >>> 0, 5);
|
|
43
|
-
}
|
|
44
|
-
return { S, acc: scramble(acc) };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const S = new Array(61);
|
|
48
|
-
let hash = 0x811c9dc5;
|
|
49
|
-
for (let i = 0; i < keyStr.length; i++) {
|
|
50
|
-
hash = Math.imul(hash ^ keyStr.charCodeAt(i), 0x1000193) >>> 0;
|
|
51
|
-
}
|
|
52
|
-
let n = scramble(scramble(hash) ^ scramble((seedStr >>> 0) ^ 0x9e3779b9)) >>> 0;
|
|
53
|
-
for (let i = 0; i < 8; i++) {
|
|
54
|
-
if (isEven(i)) {
|
|
55
|
-
const idx = n % 61;
|
|
56
|
-
n = rotl((n + 0x9e3779b9) >>> 0, 7 + (7 & i));
|
|
57
|
-
S[idx] = (n ^ scramble(n)) >>> 0;
|
|
58
|
-
n = scramble((n + idx) >>> 0);
|
|
59
|
-
} else {
|
|
60
|
-
S[i] = K[15 & i];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
S,
|
|
65
|
-
acc: scramble(0xa5a5a5a5 ^ n) >>> 0
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function nextKeystreamWord(state, step) {
|
|
70
|
-
const S = state.S;
|
|
71
|
-
let acc = state.acc;
|
|
72
|
-
const idx = acc % 61;
|
|
73
|
-
const hasIdx = 0 - Number(idx in S);
|
|
74
|
-
const sVal = S[idx] >>> 0;
|
|
75
|
-
const c = Math.imul(0x9e3779b9, step + 1) >>> 0;
|
|
76
|
-
let b = ((acc ^ ((sVal ^ c) >>> 0)) >>> 0 | (acc & (sVal ^ c) & hasIdx) >>> 0) >>> 0;
|
|
77
|
-
b = (rotl((b + acc) >>> 0, 31 & idx) ^ rotl(acc, 31 & Math.imul(idx, 7))) >>> 0;
|
|
78
|
-
acc = scramble((b + 0x9e3779b9) >>> 0);
|
|
79
|
-
S[idx] = acc >>> 0;
|
|
80
|
-
state.acc = acc;
|
|
81
|
-
return acc >>> 0;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function decodeBase64Url(str) {
|
|
85
|
-
const padded = str.replace(/-/g,
|
|
86
|
-
const bin = atob(padded);
|
|
87
|
-
const bytes = new Uint8Array(bin.length);
|
|
88
|
-
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
89
|
-
return bytes;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function decryptPayload(ciphertext, seed, mediaId) {
|
|
93
|
-
const rawBytes = decodeBase64Url(ciphertext);
|
|
94
|
-
const totalLen = rawBytes.length;
|
|
95
|
-
const state = initCipherState(seed, mediaId);
|
|
96
|
-
const keystream = new Uint8Array(totalLen);
|
|
97
|
-
|
|
98
|
-
let byteIdx = 0;
|
|
99
|
-
let step = 0;
|
|
100
|
-
while (byteIdx < totalLen) {
|
|
101
|
-
const word = nextKeystreamWord(state, step++);
|
|
102
|
-
keystream[byteIdx++] = 255 & word;
|
|
103
|
-
if (byteIdx < totalLen) keystream[byteIdx++] = (word >>> 8) & 255;
|
|
104
|
-
if (byteIdx < totalLen) keystream[byteIdx++] = (word >>> 16) & 255;
|
|
105
|
-
if (byteIdx < totalLen) keystream[byteIdx++] = (word >>> 24) & 255;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
for (let i = 0; i < totalLen; i++) {
|
|
109
|
-
rawBytes[i] ^= keystream[i];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
for (let i = 0; i < MAGIC.length; i++) {
|
|
113
|
-
if (rawBytes[i] !== MAGIC[i]) {
|
|
114
|
-
throw new Error(
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const payload = rawBytes.subarray(MAGIC.length);
|
|
119
|
-
return new TextDecoder(
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export async function getStream(
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
} catch { }
|
|
199
|
-
|
|
200
|
-
if (allUrls.length) break;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (!allUrls.length) return null;
|
|
204
|
-
|
|
205
|
-
return {
|
|
206
|
-
url: allUrls[0].url,
|
|
207
|
-
headers: allUrls[0].headers,
|
|
208
|
-
allUrls
|
|
209
|
-
};
|
|
1
|
+
import { fetchJson, fetchText, getTmdbMetadata, resolveTmdbKey } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const K = [
|
|
4
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
|
5
|
+
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
6
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
7
|
+
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
8
|
+
];
|
|
9
|
+
const MAGIC = [109, 118, 109, 49];
|
|
10
|
+
|
|
11
|
+
const isEven = e => ((e * (e + 1)) & 1) === 0;
|
|
12
|
+
|
|
13
|
+
function scramble(e) {
|
|
14
|
+
e >>>= 0;
|
|
15
|
+
e ^= e >>> 16;
|
|
16
|
+
e = Math.imul(e, 0x85ebca6b) >>> 0;
|
|
17
|
+
e ^= e >>> 13;
|
|
18
|
+
e = Math.imul(e, 0xc2b2ae35) >>> 0;
|
|
19
|
+
return (e ^ (e >>> 16)) >>> 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function rotl(e, a) {
|
|
23
|
+
e >>>= 0;
|
|
24
|
+
a &= 31;
|
|
25
|
+
return a === 0 ? e >>> 0 : ((e << a) | (e >>> (32 - a))) >>> 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function initCipherState(keyStr, seedStr) {
|
|
29
|
+
let keyLen = keyStr.length;
|
|
30
|
+
if (((keyLen * (keyLen + 1)) & 1) === 1) {
|
|
31
|
+
const S = new Array(256);
|
|
32
|
+
for (let i = 0; i < 256; i++) S[i] = i;
|
|
33
|
+
let j = 0;
|
|
34
|
+
for (let i = 0; i < 256; i++) {
|
|
35
|
+
j = (j + S[i] + keyStr.charCodeAt(i % keyStr.length)) & 255;
|
|
36
|
+
const tmp = S[i];
|
|
37
|
+
S[i] = S[j];
|
|
38
|
+
S[j] = tmp;
|
|
39
|
+
}
|
|
40
|
+
let acc = 0x67452301;
|
|
41
|
+
for (let i = 0; i < keyStr.length; i++) {
|
|
42
|
+
acc = rotl((acc ^ Math.imul(keyStr.charCodeAt(i), K[15 & i])) >>> 0, 5);
|
|
43
|
+
}
|
|
44
|
+
return { S, acc: scramble(acc) };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const S = new Array(61);
|
|
48
|
+
let hash = 0x811c9dc5;
|
|
49
|
+
for (let i = 0; i < keyStr.length; i++) {
|
|
50
|
+
hash = Math.imul(hash ^ keyStr.charCodeAt(i), 0x1000193) >>> 0;
|
|
51
|
+
}
|
|
52
|
+
let n = scramble(scramble(hash) ^ scramble((seedStr >>> 0) ^ 0x9e3779b9)) >>> 0;
|
|
53
|
+
for (let i = 0; i < 8; i++) {
|
|
54
|
+
if (isEven(i)) {
|
|
55
|
+
const idx = n % 61;
|
|
56
|
+
n = rotl((n + 0x9e3779b9) >>> 0, 7 + (7 & i));
|
|
57
|
+
S[idx] = (n ^ scramble(n)) >>> 0;
|
|
58
|
+
n = scramble((n + idx) >>> 0);
|
|
59
|
+
} else {
|
|
60
|
+
S[i] = K[15 & i];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
S,
|
|
65
|
+
acc: scramble(0xa5a5a5a5 ^ n) >>> 0,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function nextKeystreamWord(state, step) {
|
|
70
|
+
const S = state.S;
|
|
71
|
+
let acc = state.acc;
|
|
72
|
+
const idx = acc % 61;
|
|
73
|
+
const hasIdx = 0 - Number(idx in S);
|
|
74
|
+
const sVal = S[idx] >>> 0;
|
|
75
|
+
const c = Math.imul(0x9e3779b9, step + 1) >>> 0;
|
|
76
|
+
let b = ((acc ^ ((sVal ^ c) >>> 0)) >>> 0 | (acc & (sVal ^ c) & hasIdx) >>> 0) >>> 0;
|
|
77
|
+
b = (rotl((b + acc) >>> 0, 31 & idx) ^ rotl(acc, 31 & Math.imul(idx, 7))) >>> 0;
|
|
78
|
+
acc = scramble((b + 0x9e3779b9) >>> 0);
|
|
79
|
+
S[idx] = acc >>> 0;
|
|
80
|
+
state.acc = acc;
|
|
81
|
+
return acc >>> 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function decodeBase64Url(str) {
|
|
85
|
+
const padded = str.replace(/-/g, '+').replace(/_/g, '/').padEnd(4 * Math.ceil(str.length / 4), '=');
|
|
86
|
+
const bin = atob(padded);
|
|
87
|
+
const bytes = new Uint8Array(bin.length);
|
|
88
|
+
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
89
|
+
return bytes;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function decryptPayload(ciphertext, seed, mediaId) {
|
|
93
|
+
const rawBytes = decodeBase64Url(ciphertext);
|
|
94
|
+
const totalLen = rawBytes.length;
|
|
95
|
+
const state = initCipherState(seed, mediaId);
|
|
96
|
+
const keystream = new Uint8Array(totalLen);
|
|
97
|
+
|
|
98
|
+
let byteIdx = 0;
|
|
99
|
+
let step = 0;
|
|
100
|
+
while (byteIdx < totalLen) {
|
|
101
|
+
const word = nextKeystreamWord(state, step++);
|
|
102
|
+
keystream[byteIdx++] = 255 & word;
|
|
103
|
+
if (byteIdx < totalLen) keystream[byteIdx++] = (word >>> 8) & 255;
|
|
104
|
+
if (byteIdx < totalLen) keystream[byteIdx++] = (word >>> 16) & 255;
|
|
105
|
+
if (byteIdx < totalLen) keystream[byteIdx++] = (word >>> 24) & 255;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (let i = 0; i < totalLen; i++) {
|
|
109
|
+
rawBytes[i] ^= keystream[i];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < MAGIC.length; i++) {
|
|
113
|
+
if (rawBytes[i] !== MAGIC[i]) {
|
|
114
|
+
throw new Error('decrypt failed: bad seed or tampered payload');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const payload = rawBytes.subarray(MAGIC.length);
|
|
119
|
+
return new TextDecoder('utf-8').decode(payload);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function getStream(args) {
|
|
123
|
+
const { id, s, e, sdk } = args || {};
|
|
124
|
+
const isTv = s != null && e != null;
|
|
125
|
+
const type = isTv ? 'tv' : 'movie';
|
|
126
|
+
const apiKey = resolveTmdbKey(args, sdk);
|
|
127
|
+
|
|
128
|
+
const headers = {
|
|
129
|
+
Accept: '*/*',
|
|
130
|
+
Origin: 'https://www.movy.sx',
|
|
131
|
+
Referer: 'https://www.movy.sx/',
|
|
132
|
+
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1',
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const meta = await getTmdbMetadata(id, isTv, apiKey);
|
|
136
|
+
const title = meta?.title || '';
|
|
137
|
+
const year = meta?.year ? String(meta.year) : '';
|
|
138
|
+
const imdbId = meta?.imdbId || '';
|
|
139
|
+
|
|
140
|
+
if (!title) return null;
|
|
141
|
+
|
|
142
|
+
const seedRes = await fetchJson(`https://api.wecollege.net/seed?mediaId=${id}`, { headers }).catch(() => null);
|
|
143
|
+
const seed = seedRes?.seed;
|
|
144
|
+
if (!seed) return null;
|
|
145
|
+
|
|
146
|
+
const servers = ['miami', 'boise', 'vegas', 'chicago', 'reno', 'seattle'];
|
|
147
|
+
const allUrls = [];
|
|
148
|
+
|
|
149
|
+
for (const srv of servers) {
|
|
150
|
+
const params = new URLSearchParams({
|
|
151
|
+
title,
|
|
152
|
+
mediaType: type,
|
|
153
|
+
year: String(year),
|
|
154
|
+
episodeId: String(e || 1),
|
|
155
|
+
seasonId: String(s || 1),
|
|
156
|
+
tmdbId: String(id),
|
|
157
|
+
imdbId: String(imdbId || ''),
|
|
158
|
+
enc: '2',
|
|
159
|
+
seed,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const url = `https://api.wecollege.net/${srv}/sources?${params.toString()}`;
|
|
163
|
+
const rawEnc = await fetchText(url, { headers }).catch(() => null);
|
|
164
|
+
if (!rawEnc || rawEnc.length < 20 || rawEnc.startsWith('{') || rawEnc.startsWith('<')) continue;
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const dec = decryptPayload(rawEnc.trim(), seed, id);
|
|
168
|
+
const parsed = JSON.parse(dec);
|
|
169
|
+
|
|
170
|
+
if (Array.isArray(parsed?.sources)) {
|
|
171
|
+
for (const src of parsed.sources) {
|
|
172
|
+
if (src?.url) {
|
|
173
|
+
allUrls.push({
|
|
174
|
+
url: src.url,
|
|
175
|
+
server: `Movy - ${srv.toUpperCase()} (${src.quality || 'Auto'})`,
|
|
176
|
+
quality: src.quality || 'Auto',
|
|
177
|
+
type: src.url.includes('.m3u8') ? 'hls' : 'mp4',
|
|
178
|
+
headers: {
|
|
179
|
+
Referer: 'https://www.movy.sx/',
|
|
180
|
+
Origin: 'https://www.movy.sx',
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch { }
|
|
187
|
+
|
|
188
|
+
if (allUrls.length) break;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!allUrls.length) return null;
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
url: allUrls[0].url,
|
|
195
|
+
headers: allUrls[0].headers,
|
|
196
|
+
allUrls,
|
|
197
|
+
};
|
|
210
198
|
}
|
package/src/sources/net79.js
CHANGED
|
@@ -1,56 +1,60 @@
|
|
|
1
|
-
import { fetchJson } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
1
|
+
import { fetchJson } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://net79.cc';
|
|
4
|
+
|
|
5
|
+
export async function getStream(args) {
|
|
6
|
+
const { id, s, e } = args || {};
|
|
7
|
+
const isTv = s != null && e != null;
|
|
8
|
+
|
|
9
|
+
const url = isTv
|
|
10
|
+
? `${BASE_URL}/api/embed-tmdb/${id}?type=tv&se=${s}&ep=${e}`
|
|
11
|
+
: `${BASE_URL}/api/embed-tmdb/${id}?type=movie`;
|
|
12
|
+
|
|
13
|
+
const headers = {
|
|
14
|
+
Accept: 'application/json',
|
|
15
|
+
Referer: `${BASE_URL}/`,
|
|
16
|
+
Origin: BASE_URL,
|
|
17
|
+
'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',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const res = await fetchJson(url, { headers }).catch(() => null);
|
|
21
|
+
if (!res || !res.ok || res.noSource) return null;
|
|
22
|
+
|
|
23
|
+
const allUrls = [];
|
|
24
|
+
|
|
25
|
+
if (Array.isArray(res.streams) && res.streams.length > 0) {
|
|
26
|
+
for (const stream of res.streams) {
|
|
27
|
+
if (stream?.url) {
|
|
28
|
+
allUrls.push({
|
|
29
|
+
url: stream.url,
|
|
30
|
+
quality: stream.resolution ? `${stream.resolution}p` : 'Auto',
|
|
31
|
+
server: `Net79 - ${stream.resolution ? `${stream.resolution}p` : 'MP4'}`,
|
|
32
|
+
type: stream.url.includes('.m3u8') ? 'hls' : 'mp4',
|
|
33
|
+
headers: {
|
|
34
|
+
Referer: `${BASE_URL}/`,
|
|
35
|
+
Origin: BASE_URL,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} else if (res.mp4) {
|
|
41
|
+
allUrls.push({
|
|
42
|
+
url: res.mp4,
|
|
43
|
+
quality: res.resolution ? `${res.resolution}p` : 'Auto',
|
|
44
|
+
server: `Net79 - ${res.resolution ? `${res.resolution}p` : 'MP4'}`,
|
|
45
|
+
type: res.mp4.includes('.m3u8') ? 'hls' : 'mp4',
|
|
46
|
+
headers: {
|
|
47
|
+
Referer: `${BASE_URL}/`,
|
|
48
|
+
Origin: BASE_URL,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!allUrls.length) return null;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
url: allUrls[0].url,
|
|
57
|
+
headers: allUrls[0].headers,
|
|
58
|
+
allUrls,
|
|
59
|
+
};
|
|
56
60
|
}
|