@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/vidzee.js
CHANGED
|
@@ -1,184 +1,190 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const BASE_URL = 'https://core.vidzee.wtf';
|
|
4
|
-
const PLAYER_URL = 'https://player.vidzee.wtf';
|
|
5
|
-
const SERVICES = ['dcloud', 'ipcloud', 'tik', 'v6:Hindi', '3AHindi'];
|
|
6
|
-
const WASM_B64 = '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';
|
|
7
|
-
|
|
8
|
-
let wasmInstanceCache = null;
|
|
9
|
-
|
|
10
|
-
async function getWasmInstance() {
|
|
11
|
-
if (wasmInstanceCache) return wasmInstanceCache;
|
|
12
|
-
try {
|
|
13
|
-
const wasmBuffer = Buffer.from(WASM_B64, 'base64');
|
|
14
|
-
const wasmModule = await WebAssembly.compile(wasmBuffer);
|
|
15
|
-
|
|
16
|
-
let memory;
|
|
17
|
-
let exports;
|
|
18
|
-
|
|
19
|
-
const env = {
|
|
20
|
-
abort() {
|
|
21
|
-
throw new Error('WASM abort');
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const res = await WebAssembly.instantiate(wasmModule, { env });
|
|
26
|
-
exports = res.exports;
|
|
27
|
-
memory = exports.memory;
|
|
28
|
-
|
|
29
|
-
const refMap = new Map();
|
|
30
|
-
function pin(ptr) {
|
|
31
|
-
if (ptr) {
|
|
32
|
-
const count = refMap.get(ptr);
|
|
33
|
-
if (count) refMap.set(ptr, count + 1);
|
|
34
|
-
else refMap.set(exports.__pin(ptr), 1);
|
|
35
|
-
}
|
|
36
|
-
return ptr;
|
|
37
|
-
}
|
|
38
|
-
function unpin(ptr) {
|
|
39
|
-
if (ptr) {
|
|
40
|
-
const count = refMap.get(ptr);
|
|
41
|
-
if (count === 1) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
} else if (count) {
|
|
45
|
-
refMap.set(ptr, count - 1);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
wasmInstanceCache = {
|
|
51
|
-
decrypt(encryptedBytes, keyStr) {
|
|
52
|
-
let dataPtr = 0;
|
|
53
|
-
let keyPtr = 0;
|
|
54
|
-
try {
|
|
55
|
-
const len = encryptedBytes.length;
|
|
56
|
-
const pinPtr = exports.__pin(exports.__new(len, 1)) >>> 0;
|
|
57
|
-
dataPtr = exports.__new(12, 6) >>> 0;
|
|
58
|
-
|
|
59
|
-
const view = new DataView(memory.buffer);
|
|
60
|
-
view.setUint32(dataPtr, pinPtr, true);
|
|
61
|
-
view.setUint32(dataPtr + 4, pinPtr, true);
|
|
62
|
-
view.setUint32(dataPtr + 8, len, true);
|
|
63
|
-
new Uint8Array(memory.buffer, pinPtr, len).set(encryptedBytes);
|
|
64
|
-
exports.__unpin(pinPtr);
|
|
65
|
-
|
|
66
|
-
pin(dataPtr);
|
|
67
|
-
|
|
68
|
-
const kLen = keyStr.length;
|
|
69
|
-
keyPtr = exports.__new(kLen << 1, 2) >>> 0;
|
|
70
|
-
const u16View = new Uint16Array(memory.buffer);
|
|
71
|
-
for (let i = 0; i < kLen; i++) {
|
|
72
|
-
u16View[(keyPtr >>> 1) + i] = keyStr.charCodeAt(i);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const resPtr = exports.decrypt(dataPtr, keyPtr) >>> 0;
|
|
76
|
-
if (!resPtr) return new Uint8Array(0);
|
|
77
|
-
|
|
78
|
-
const resView = new DataView(memory.buffer);
|
|
79
|
-
const outPtr = resView.getUint32(resPtr + 4, true);
|
|
80
|
-
const outLen = resView.getUint32(resPtr + 8, true);
|
|
81
|
-
return new Uint8Array(memory.buffer, outPtr, outLen).slice();
|
|
82
|
-
} finally {
|
|
83
|
-
unpin(dataPtr);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
return wasmInstanceCache;
|
|
88
|
-
} catch {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function requestEndpoint(url, headers) {
|
|
94
|
-
try {
|
|
95
|
-
return await fetchJson(url, {
|
|
96
|
-
headers,
|
|
97
|
-
signal: AbortSignal.timeout(6000)
|
|
98
|
-
});
|
|
99
|
-
} catch {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function resolveServiceStream(service, isMovie, id, s, e, headers) {
|
|
105
|
-
const directEndpoint = isMovie
|
|
106
|
-
? `${BASE_URL}/streams/movie/${id}?s=${service}`
|
|
107
|
-
: `${BASE_URL}/streams/tv/${id}/${s || 1}/${e || 1}?s=${service}`;
|
|
108
|
-
|
|
109
|
-
let res = await requestEndpoint(directEndpoint, headers);
|
|
110
|
-
|
|
111
|
-
if (!res || !res.url) {
|
|
112
|
-
const encEndpoint = `${directEndpoint}&e=1`;
|
|
113
|
-
const encRes = await requestEndpoint(encEndpoint, headers);
|
|
114
|
-
|
|
115
|
-
if (encRes && encRes.c) {
|
|
116
|
-
const instance = await getWasmInstance();
|
|
117
|
-
if (instance) {
|
|
118
|
-
const encryptedBytes = new Uint8Array(Buffer.from(encRes.c, 'base64'));
|
|
119
|
-
const decryptedBytes = instance.decrypt(encryptedBytes, 'player.vidzee.wtf');
|
|
120
|
-
if (decryptedBytes.length > 0) {
|
|
121
|
-
const str = new TextDecoder().decode(decryptedBytes);
|
|
122
|
-
try {
|
|
123
|
-
res = JSON.parse(str);
|
|
124
|
-
} catch { }
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (res && res.url) {
|
|
131
|
-
const format = res.url.includes('.m3u8') ? 'hls' : 'mp4';
|
|
132
|
-
return {
|
|
133
|
-
url: res.url,
|
|
134
|
-
server: `VidZee (${service})`,
|
|
135
|
-
quality: res.language || 'Auto',
|
|
136
|
-
type: format,
|
|
137
|
-
headers: {
|
|
138
|
-
'User-Agent': USER_AGENT,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
...(res.headers || {})
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export async function getStream(args) {
|
|
149
|
-
const { id, s, e, server, clientIP } = args;
|
|
150
|
-
const isTv = s != null && e != null;
|
|
151
|
-
const isMovie = !isTv;
|
|
152
|
-
|
|
153
|
-
const headers = {
|
|
154
|
-
'User-Agent': USER_AGENT,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
...(clientIP && { 'X-Forwarded-For': clientIP })
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
let targets = SERVICES;
|
|
162
|
-
if (server && server !== 'all') {
|
|
163
|
-
const clean = server.toLowerCase().replace('vidzee (', '').replace(')', '').replace('vidzee', '').trim();
|
|
164
|
-
targets = SERVICES.filter(srv => srv.toLowerCase().includes(clean));
|
|
165
|
-
if (!targets.length) targets = SERVICES;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const settled = await Promise.allSettled(
|
|
169
|
-
targets.map(service => resolveServiceStream(service, isMovie, id, s, e, headers))
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const allUrls = [];
|
|
173
|
-
for (const r of settled) {
|
|
174
|
-
if (r.status === 'fulfilled' && r.value) {
|
|
175
|
-
allUrls.push(r.value);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
1
|
+
import { fetchJson, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://core.vidzee.wtf';
|
|
4
|
+
const PLAYER_URL = 'https://player.vidzee.wtf';
|
|
5
|
+
const SERVICES = ['dcloud', 'ipcloud', 'tik', 'v6:Hindi', '3AHindi'];
|
|
6
|
+
const WASM_B64 = 'AGFzbQEAAAABPgtgAX8Bf2ACf38Bf2ABfwBgAn9/AGADf39/AGAAAGAEf39/fwBgBH9/f38Bf2ADf39/AX9gA39/fgBgAAF/Ag0BA2VudgVhYm9ydAAGAygnAgEAAAQBAAEDBAADBQAAAgMHAAEAAAQIAwEJAgIBBQAAAgEABQoBBQMBAAEGJgd/AUEAC38BQQALfwFBAAt/AUEAC38BQQALfwFBAAt/AEGA2wALB0gHB2RlY3J5cHQAJwVfX25ldwAGBV9fcGluACQHX191bnBpbgAiCV9fY29sbGVjdAAlC19fcnR0aV9iYXNlAwYGbWVtb3J5AgAIAR8MAqkBCogkJyUAIABFBEAPCyAAQRRrIgAQByMCRgRAIAAQECAAIwUjAkUQCgsLCgAgACABai0AAAsKACAAKAIEQXxxCw0AIABBFGsoAhBBAXYLDAAgACABaiACOgAAC1MBAX8gAEHs////A0sEQEHwDEGwDUH9AEEeEAAACyMARQRAEA0LIwAgAEEQahAaIgIgATYCDCACIAA2AhAgAiMBIwIQCiACEAsjA2okAyACQRRqCwoAIAAoAgRBA3ELKQAgACAAIAFBCHZqLQAAQQV0aiABQf8BcUEDdmotAAAgAUEHcXZBAXELwwEBBH8gASgCAEF8cSIDQYACSQR/IANBBHYFQR9B/P///wMgAyADQfz///8DTxsiA2drIgRBB2shAiADIARBBGt2QRBzCyEEIAEoAgghBSABKAIEIgMEQCADIAU2AggLIAUEQCAFIAM2AgQLIAEgACACQQR0IARqQQJ0aiIBKAJgRgRAIAEgBTYCYCAFRQRAIAAgAkECdGoiASgCBEF+IAR3cSEDIAEgAzYCBCADRQRAIAAgACgCAEF+IAJ3cTYCAAsLCwspAQF/IAEoAgghAyAAIAEgAnI2AgQgACADNgIIIAMgABARIAEgADYCCAsNACAAKAIAQXxxQQRqC7wCAQV/IAEoAgAhAyABQQRqIAEoAgBBfHFqIgQoAgAiAkEBcQRAIAAgBBAJIAEgA0EEaiACQXxxaiIDNgIAIAFBBGogASgCAEF8cWoiBCgCACECCyADQQJxBEAgAUEEaygCACIBKAIAIQYgACABEAkgASAGQQRqIANBfHFqIgM2AgALIAQgAkECcjYCACAEQQRrIAE2AgAgACADQXxxIgJBgAJJBH8gAkEEdgVBH0H8////AyACIAJB/P///wNPGyICZ2siA0EHayEFIAIgA0EEa3ZBEHMLIgIgBUEEdGpBAnRqKAJgIQMgAUEANgIEIAEgAzYCCCADBEAgAyABNgIECyAAIAVBBHQgAmpBAnRqIAE2AmAgACAAKAIAQQEgBXRyNgIAIAAgBUECdGoiACAAKAIEQQEgAnRyNgIEC5cBAQJ/PwAiAEEATAR/QQEgAGtAAEEASAVBAAsEQAALQbDbAEEANgIAQdDnAEEANgIAA0AgAUEXSQRAIAFBAnRBsNsAakEANgIEQQAhAANAIABBEEkEQCABQQR0IABqQQJ0QbDbAGkBADYCYCAAQQFqIQAMAQsLIAFBAWohAQwBCwtBsNsAQdTnAD8ArEIQhhAbQbDbACQACyYBAX8gAEEEayEBIABBD3FBASAAGwR/QQEFIAEoAgBBAXELGiABCxIAIAAgADYCBCAAIAA2AgggAAsnAQF/IAAQAyIBRQRAIAAoAggaDwsgASAAKAIIIgA2AgggACABEBELEgAgACABIAAoAgRBA3FyNgIEC0kBAX8gACABQQF0aiEBA0AgAyIAQQFrIQMgAARAIAEvAQAiACACLwEAIgRHBEAgACAEaw8LIAFBAmohASACQQJqIQIMAQsLQQALbgECf0EMQQYQBiIBRQRAQQxBAxAGIQELIAFBADYCACABQQA2AgQgAUEANgIIIABB/P///wNLBEBB4NcAQZDYAEETQTkQAAALIABBARAGIgJBACAA/AsAIAEgAjYCACABIAI2AgQgASAANgIIIAELjgEBAn8gAUGAAkkEfyABQQR2BUEfIAEQFSIBZ2siA0EHayECIAEgA0EEa3ZBEHMLIgEgACACQQJ0aigCBEF/IAF0cSIBBH8gACABaCACQQR0akECdGooAmAFIAAoAgBBfyACQQFqdHEiAQR/IAAgACABaCIAQQJ0aigCBGggAEEEdGpBAnRqKAJgBUEACwsLHQAgAEEBQRsgAGdrdGpBAWsgACAAQf7///8BSRsLLwAgAEH8////A0sEQEHwDEHwDUHNA0EdEAAAC0EMIABBE2pBcHFBBGsgAEEMTRsLZwECfyABKAIAIgNBfHEgAmsiBEEQTwRAIAEgAiADQQJxcjYCACABQQRqIAJqIgEgBEEEa0EBcjYCACAAIAEQDAUgASADQX5xNgIAIAFBBGogASgCAEF8cWoiACAAKAIAQX1xNgIACwswACAAIAIQGiICQQRqIAFBBGogASgCAEF8cfwKAAAgAUGk2wBPBEAgACABEBkLIAILFQAgASABKAIAQQFyNgIAIAAgARAMC48BAQJ/IAAgARAWIgIQFCIBRQRAQQQgACgCoAw/ACIBQRB0QQRrR3QgAhAVIAIgAkGAAk8bakH//wNqQYCAfHFBEHYhAyABIAMgASADShtAAEEASARAIANAAEEASARAAAsLIAAgAUEQdD8ArEIQhhAbIAAgAhAUIQELIAEoAgAaIAAgARAJIAAgASACEBcgAQuGAQEDfyABQRNqQXBxQQRrIQEgACgCoAwiAwRAIAFBEGsiBSADRgRAIAMoAgAhBCAFIQELCyACp0FwcSABayIDQRRJBEAPCyABIARBAnEgA0EIayIDQQFycjYCACABQQA2AgQgAUEANgIIIAFBBGogA2oiA0ECNgIAIAAgAzYCoAwgACABEAwLhQEBA38CQAJAAkACQAJAAkACQAJAAkAgAEEIaygCAA4IAAECAwQFBgcICw8LDwsPCyAAEB0PCyAAKAIAEAEPCyAAKAIEIgEgACgCDEECdGohAgNAIAEgAkkEQCABKAIAIgMEQCADEAELIAFBBGohAQwBCwsgACgCABABDwsgABAdDwsPCwALCQAgACgCABABC0MAIAEgACgCDE8EQEHw1QBBsNYAQfIAQSoQAAALIAAoAgQgAUECdGooAgAiAEUEQEHg1gBBsNYAQfYAQSgQAAALIAALGQBBoA4QDyQBQYDaABAPJARB4NoAEA8kBQv9AQEGfyAAIgFBCHYiAkHMzgBqLQAAIAJBlDJqLQAAQdYAbEGUMmogAEH/AXEiA0EDbmotAAAgA0EDcEECdEGAxwBqKAIAbEELdkEGcGpBAnRBjbrowserigCACICQf8BcSEAIAJBCHUhAgJAIABBAkkNACACQf8BcSEAIAJBCHYhAgNAIAAEQCAAQQF2IgYgAmpBAXRBzNIAaiIELQAAIgUgA0YEfyAELQABQQJ0QYzHAGooAgAiAkH/AXEhACACQQh1IQIgAEECSQ0DIAFBAWoPBSADIAVJBH8gBgUgAiAGaiECIAAgBmsLCyEADAELCyABDwsgASACQQAgAGtxag==';
|
|
7
|
+
|
|
8
|
+
let wasmInstanceCache = null;
|
|
9
|
+
|
|
10
|
+
async function getWasmInstance() {
|
|
11
|
+
if (wasmInstanceCache) return wasmInstanceCache;
|
|
12
|
+
try {
|
|
13
|
+
const wasmBuffer = Buffer.from(WASM_B64, 'base64');
|
|
14
|
+
const wasmModule = await WebAssembly.compile(wasmBuffer);
|
|
15
|
+
|
|
16
|
+
let memory;
|
|
17
|
+
let exports;
|
|
18
|
+
|
|
19
|
+
const env = {
|
|
20
|
+
abort() {
|
|
21
|
+
throw new Error('WASM abort');
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const res = await WebAssembly.instantiate(wasmModule, { env });
|
|
26
|
+
exports = res.exports;
|
|
27
|
+
memory = exports.memory;
|
|
28
|
+
|
|
29
|
+
const refMap = new Map();
|
|
30
|
+
function pin(ptr) {
|
|
31
|
+
if (ptr) {
|
|
32
|
+
const count = refMap.get(ptr);
|
|
33
|
+
if (count) refMap.set(ptr, count + 1);
|
|
34
|
+
else refMap.set(exports.__pin(ptr), 1);
|
|
35
|
+
}
|
|
36
|
+
return ptr;
|
|
37
|
+
}
|
|
38
|
+
function unpin(ptr) {
|
|
39
|
+
if (ptr) {
|
|
40
|
+
const count = refMap.get(ptr);
|
|
41
|
+
if (count === 1) {
|
|
42
|
+
refMap.delete(ptr);
|
|
43
|
+
exports.__unpin(ptr);
|
|
44
|
+
} else if (count > 1) {
|
|
45
|
+
refMap.set(ptr, count - 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
wasmInstanceCache = {
|
|
51
|
+
decrypt(encryptedBytes, keyStr) {
|
|
52
|
+
let dataPtr = 0;
|
|
53
|
+
let keyPtr = 0;
|
|
54
|
+
try {
|
|
55
|
+
const len = encryptedBytes.length;
|
|
56
|
+
const pinPtr = exports.__pin(exports.__new(len, 1)) >>> 0;
|
|
57
|
+
dataPtr = exports.__new(12, 6) >>> 0;
|
|
58
|
+
|
|
59
|
+
const view = new DataView(memory.buffer);
|
|
60
|
+
view.setUint32(dataPtr, pinPtr, true);
|
|
61
|
+
view.setUint32(dataPtr + 4, pinPtr, true);
|
|
62
|
+
view.setUint32(dataPtr + 8, len, true);
|
|
63
|
+
new Uint8Array(memory.buffer, pinPtr, len).set(encryptedBytes);
|
|
64
|
+
exports.__unpin(pinPtr);
|
|
65
|
+
|
|
66
|
+
pin(dataPtr);
|
|
67
|
+
|
|
68
|
+
const kLen = keyStr.length;
|
|
69
|
+
keyPtr = exports.__new(kLen << 1, 2) >>> 0;
|
|
70
|
+
const u16View = new Uint16Array(memory.buffer);
|
|
71
|
+
for (let i = 0; i < kLen; i++) {
|
|
72
|
+
u16View[(keyPtr >>> 1) + i] = keyStr.charCodeAt(i);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const resPtr = exports.decrypt(dataPtr, keyPtr) >>> 0;
|
|
76
|
+
if (!resPtr) return new Uint8Array(0);
|
|
77
|
+
|
|
78
|
+
const resView = new DataView(memory.buffer);
|
|
79
|
+
const outPtr = resView.getUint32(resPtr + 4, true);
|
|
80
|
+
const outLen = resView.getUint32(resPtr + 8, true);
|
|
81
|
+
return new Uint8Array(memory.buffer, outPtr, outLen).slice();
|
|
82
|
+
} finally {
|
|
83
|
+
unpin(dataPtr);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
return wasmInstanceCache;
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function requestEndpoint(url, headers) {
|
|
94
|
+
try {
|
|
95
|
+
return await fetchJson(url, {
|
|
96
|
+
headers,
|
|
97
|
+
signal: AbortSignal.timeout(6000),
|
|
98
|
+
});
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function resolveServiceStream(service, isMovie, id, s, e, headers) {
|
|
105
|
+
const directEndpoint = isMovie
|
|
106
|
+
? `${BASE_URL}/streams/movie/${id}?s=${service}`
|
|
107
|
+
: `${BASE_URL}/streams/tv/${id}/${s || 1}/${e || 1}?s=${service}`;
|
|
108
|
+
|
|
109
|
+
let res = await requestEndpoint(directEndpoint, headers);
|
|
110
|
+
|
|
111
|
+
if (!res || !res.url) {
|
|
112
|
+
const encEndpoint = `${directEndpoint}&e=1`;
|
|
113
|
+
const encRes = await requestEndpoint(encEndpoint, headers);
|
|
114
|
+
|
|
115
|
+
if (encRes && encRes.c) {
|
|
116
|
+
const instance = await getWasmInstance();
|
|
117
|
+
if (instance) {
|
|
118
|
+
const encryptedBytes = new Uint8Array(Buffer.from(encRes.c, 'base64'));
|
|
119
|
+
const decryptedBytes = instance.decrypt(encryptedBytes, 'player.vidzee.wtf');
|
|
120
|
+
if (decryptedBytes.length > 0) {
|
|
121
|
+
const str = new TextDecoder().decode(decryptedBytes);
|
|
122
|
+
try {
|
|
123
|
+
res = JSON.parse(str);
|
|
124
|
+
} catch { }
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (res && res.url) {
|
|
131
|
+
const format = res.url.includes('.m3u8') ? 'hls' : 'mp4';
|
|
132
|
+
return {
|
|
133
|
+
url: res.url,
|
|
134
|
+
server: `VidZee (${service})`,
|
|
135
|
+
quality: res.language || 'Auto',
|
|
136
|
+
type: format,
|
|
137
|
+
headers: {
|
|
138
|
+
'User-Agent': USER_AGENT,
|
|
139
|
+
Referer: `${PLAYER_URL}/`,
|
|
140
|
+
Origin: PLAYER_URL,
|
|
141
|
+
...(res.headers || {}),
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export async function getStream(args) {
|
|
149
|
+
const { id, s, e, server, clientIP } = args || {};
|
|
150
|
+
const isTv = s != null && e != null;
|
|
151
|
+
const isMovie = !isTv;
|
|
152
|
+
|
|
153
|
+
const headers = {
|
|
154
|
+
'User-Agent': USER_AGENT,
|
|
155
|
+
Accept: 'application/json, text/plain, */*',
|
|
156
|
+
Referer: `${PLAYER_URL}/`,
|
|
157
|
+
Origin: PLAYER_URL,
|
|
158
|
+
...(clientIP && { 'X-Forwarded-For': clientIP }),
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
let targets = SERVICES;
|
|
162
|
+
if (server && server !== 'all') {
|
|
163
|
+
const clean = server.toLowerCase().replace('vidzee (', '').replace(')', '').replace('vidzee', '').trim();
|
|
164
|
+
targets = SERVICES.filter(srv => srv.toLowerCase().includes(clean));
|
|
165
|
+
if (!targets.length) targets = SERVICES;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const settled = await Promise.allSettled(
|
|
169
|
+
targets.map(service => resolveServiceStream(service, isMovie, id, s, e, headers))
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const allUrls = [];
|
|
173
|
+
for (const r of settled) {
|
|
174
|
+
if (r.status === 'fulfilled' && r.value) {
|
|
175
|
+
allUrls.push(r.value);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!allUrls.length) return null;
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
url: allUrls[0].url,
|
|
183
|
+
headers: allUrls[0].headers,
|
|
184
|
+
allUrls,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export async function getSources() {
|
|
189
|
+
return SERVICES.map(s => `VidZee (${s})`);
|
|
184
190
|
}
|
package/src/sources/vixsrc.js
CHANGED
|
@@ -1,114 +1,124 @@
|
|
|
1
|
-
import { fetchText, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const BASE_URL = 'https://vixsrc.to';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
'Accept': '
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
val = val.replace(
|
|
18
|
-
val = val.replace(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
if (playlist
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
1
|
+
import { fetchText, USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://vixsrc.to';
|
|
4
|
+
const HEADERS = {
|
|
5
|
+
'User-Agent': USER_AGENT,
|
|
6
|
+
Accept: 'application/json, text/javascript, */*; q=0.01',
|
|
7
|
+
'Accept-Language': 'en-US,en;q=0.9',
|
|
8
|
+
Referer: `${BASE_URL}/`,
|
|
9
|
+
Origin: BASE_URL,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function extract(regex, text) {
|
|
13
|
+
const m = text?.match(regex);
|
|
14
|
+
if (!m) return null;
|
|
15
|
+
let val = m[1];
|
|
16
|
+
val = val.replace(/\\u0026/gi, '&');
|
|
17
|
+
val = val.replace(/\\\//g, '/');
|
|
18
|
+
val = val.replace(/\\/g, '');
|
|
19
|
+
return val;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function getStream(args) {
|
|
23
|
+
const { id, s, e, absoluteBase } = args || {};
|
|
24
|
+
const isTv = s != null && e != null;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const apiUrl = isTv
|
|
28
|
+
? `${BASE_URL}/api/tv/${id}/${s}/${e}`
|
|
29
|
+
: `${BASE_URL}/api/movie/${id}`;
|
|
30
|
+
|
|
31
|
+
const apiProxy = absoluteBase && absoluteBase !== '/'
|
|
32
|
+
? `${absoluteBase.replace(/^https:\/\/(localhost|127\.0\.0\.1)/, 'http://$1')}/api?url=${encodeURIComponent(apiUrl)}&proxyHeaders=${encodeURIComponent(JSON.stringify(HEADERS))}`
|
|
33
|
+
: apiUrl;
|
|
34
|
+
|
|
35
|
+
const apiText = await fetchText(apiProxy, { headers: HEADERS }).catch(() => null);
|
|
36
|
+
const apiData = JSON.parse(apiText || '{}');
|
|
37
|
+
if (!apiData.src) return null;
|
|
38
|
+
|
|
39
|
+
const embedUrl = apiData.src.startsWith('http') ? apiData.src : `${BASE_URL}${apiData.src}`;
|
|
40
|
+
const embedProxy = absoluteBase && absoluteBase !== '/'
|
|
41
|
+
? `${absoluteBase.replace(/^https:\/\/(localhost|127\.0\.0\.1)/, 'http://$1')}/api?url=${encodeURIComponent(embedUrl)}&proxyHeaders=${encodeURIComponent(JSON.stringify(HEADERS))}`
|
|
42
|
+
: embedUrl;
|
|
43
|
+
|
|
44
|
+
const html = await fetchText(embedProxy, { headers: HEADERS }).catch(() => null);
|
|
45
|
+
if (!html) return null;
|
|
46
|
+
|
|
47
|
+
const token = extract(/token["']\s*:\s*["']([^"']+)/, html);
|
|
48
|
+
const expires = extract(/expires["']\s*:\s*["']([^"']+)/, html);
|
|
49
|
+
let playlist = extract(/url["']\s*:\s*["']([^"']+)/, html);
|
|
50
|
+
|
|
51
|
+
if (!token || !expires || !playlist) return null;
|
|
52
|
+
|
|
53
|
+
if (playlist.startsWith('/')) {
|
|
54
|
+
playlist = `${BASE_URL}${playlist}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const defaultLang = extract(/lang(?:uage)?["']\s*:\s*["']([a-z]{2,5})/i, html) || 'en';
|
|
58
|
+
const rawMasterUrl = `${playlist}${playlist.includes('?') ? '&' : '?'}token=${token}&expires=${expires}&h=1&lang=${defaultLang}`;
|
|
59
|
+
|
|
60
|
+
const masterProxy = absoluteBase && absoluteBase !== '/'
|
|
61
|
+
? `${absoluteBase.replace(/^https:\/\/(localhost|127\.0\.0\.1)/, 'http://$1')}/api?url=${encodeURIComponent(rawMasterUrl)}&proxyHeaders=${encodeURIComponent(JSON.stringify({ ...HEADERS, Referer: embedUrl }))}`
|
|
62
|
+
: rawMasterUrl;
|
|
63
|
+
|
|
64
|
+
const playlistText = await fetchText(masterProxy, { headers: { ...HEADERS, Referer: embedUrl } }).catch(() => null);
|
|
65
|
+
if (!playlistText?.includes('#EXTM3U')) return null;
|
|
66
|
+
|
|
67
|
+
const lines = playlistText.split('\n');
|
|
68
|
+
const audioTracks = [];
|
|
69
|
+
const seen = new Set();
|
|
70
|
+
|
|
71
|
+
for (const line of lines) {
|
|
72
|
+
if (line.startsWith('#EXT-X-MEDIA') && line.includes('TYPE=AUDIO')) {
|
|
73
|
+
const name = line.match(/NAME=["']([^"']+)["']/)?.[1] || 'Default';
|
|
74
|
+
const rendition = line.match(/rendition=([a-zA-Z0-9_-]+)/)?.[1]
|
|
75
|
+
|| line.match(/LANGUAGE=["']([^"']+)["']/)?.[1]
|
|
76
|
+
|| name;
|
|
77
|
+
const key = rendition.toLowerCase();
|
|
78
|
+
if (!seen.has(key)) {
|
|
79
|
+
seen.add(key);
|
|
80
|
+
audioTracks.push({ name, lang: rendition });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const allUrls = [];
|
|
86
|
+
|
|
87
|
+
if (audioTracks.length > 0) {
|
|
88
|
+
for (const track of audioTracks) {
|
|
89
|
+
const streamUrl = `${playlist}${playlist.includes('?') ? '&' : '?'}token=${token}&expires=${expires}&h=1&lang=${track.lang}`;
|
|
90
|
+
allUrls.push({
|
|
91
|
+
url: streamUrl,
|
|
92
|
+
server: `VixSrc (${track.name})`,
|
|
93
|
+
quality: 'Auto',
|
|
94
|
+
type: 'hls',
|
|
95
|
+
skipProxy: true,
|
|
96
|
+
headers: {
|
|
97
|
+
...HEADERS,
|
|
98
|
+
Referer: `${BASE_URL}/`,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
allUrls.push({
|
|
104
|
+
url: rawMasterUrl,
|
|
105
|
+
server: 'VixSrc',
|
|
106
|
+
quality: 'Auto',
|
|
107
|
+
type: 'hls',
|
|
108
|
+
skipProxy: true,
|
|
109
|
+
headers: {
|
|
110
|
+
...HEADERS,
|
|
111
|
+
Referer: `${BASE_URL}/`,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
url: allUrls[0].url,
|
|
118
|
+
headers: allUrls[0].headers,
|
|
119
|
+
allUrls,
|
|
120
|
+
};
|
|
121
|
+
} catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
114
124
|
}
|