@vyla-entertainment/sdk 1.8.0 → 1.10.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/.github/workflows/publish.yml +38 -38
- package/.gitlab-ci.yml +16 -0
- package/README.md +1 -1
- package/package.json +33 -32
- package/src/config.js +91 -34
- package/src/health.js +2 -2
- package/src/sdk.d.ts +122 -122
- package/src/sdk.js +7 -4
- package/src/sources/anineko.js +3 -1
- package/src/sources/cinejoy.js +194 -209
- package/src/sources/flaxmovies.js +113 -21
- package/src/sources/frame.js +88 -0
- package/src/sources/fsonic.js +3 -1
- package/src/sources/fsonline.js +3 -1
- package/src/sources/lmscript.js +42 -42
- package/src/sources/lookmovie.js +3 -1
- package/src/sources/luna.js +125 -0
- package/src/sources/mapple.js +40 -4
- package/src/sources/megasource.js +47 -0
- package/src/sources/meowtv.js +1 -9
- package/src/sources/nova.js +46 -0
- package/src/sources/peestream.js +122 -0
- package/src/sources/pengu.js +8 -3
- package/src/sources/rivestream.js +179 -0
- package/src/sources/videasy.js +3 -1
- package/src/sources/vidgod.js +147 -0
- package/src/sources/vidnest.js +3 -1
- package/src/sources/vidvault.js +113 -113
- package/src/sources/vidzee.js +163 -85
- package/src/utils/helpers.js +2 -2
- package/src/sources/1embed.js +0 -115
- package/src/sources/nekowatch.js +0 -57
- package/src/sources/opstream.js +0 -123
- package/src/sources/peachify.js +0 -78
package/src/sources/vidvault.js
CHANGED
|
@@ -1,114 +1,114 @@
|
|
|
1
|
-
import { USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const BASE_URL = "https://vidvault.ru";
|
|
4
|
-
const HEADERS = {
|
|
5
|
-
"Referer": `${BASE_URL}/`,
|
|
6
|
-
"Origin": BASE_URL,
|
|
7
|
-
"User-Agent": USER_AGENT,
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
async function getToken() {
|
|
11
|
-
const res = await fetch(`${BASE_URL}/api/get-token`, {
|
|
12
|
-
method: "GET",
|
|
13
|
-
headers: HEADERS
|
|
14
|
-
});
|
|
15
|
-
const data = await res.json();
|
|
16
|
-
return data.t;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getCaptionType(url) {
|
|
20
|
-
return url.toLowerCase().includes(".vtt") ? "vtt" : "srt";
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function getStream(args) {
|
|
24
|
-
const { id, s, e } = args;
|
|
25
|
-
const type = (s != null && e != null) ? "tv" : "movie";
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const token = await getToken();
|
|
29
|
-
|
|
30
|
-
const payload = { type, tmdbId: String(id) };
|
|
31
|
-
if (type === "tv") {
|
|
32
|
-
payload.season = String(s);
|
|
33
|
-
payload.episode = String(e);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const res = await fetch(`${BASE_URL}/api/download-proxy`, {
|
|
37
|
-
method: "POST",
|
|
38
|
-
headers: {
|
|
39
|
-
...HEADERS,
|
|
40
|
-
"Content-Type": "application/json",
|
|
41
|
-
"x-request-token": token
|
|
42
|
-
},
|
|
43
|
-
body: JSON.stringify(payload)
|
|
44
|
-
});
|
|
45
|
-
const data = await res.json();
|
|
46
|
-
|
|
47
|
-
const allUrls = [];
|
|
48
|
-
const subtitles = [];
|
|
49
|
-
|
|
50
|
-
const mp4 = data?.mp4Data;
|
|
51
|
-
if (mp4) {
|
|
52
|
-
const country = mp4.country || "";
|
|
53
|
-
const lanName = mp4.lanName || "";
|
|
54
|
-
const detailPath = mp4.detailPath || "";
|
|
55
|
-
|
|
56
|
-
const downloads = mp4.downloadInfo?.data?.downloads || [];
|
|
57
|
-
for (const d of downloads) {
|
|
58
|
-
if (!d?.url) continue;
|
|
59
|
-
allUrls.push({
|
|
60
|
-
quality: `${d.resolution}p ${detailPath} ${country} ${lanName}`.trim(),
|
|
61
|
-
url: d.url,
|
|
62
|
-
type: "mp4",
|
|
63
|
-
headers: HEADERS
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const srtCaptions = mp4.downloadInfo?.data?.captions || [];
|
|
68
|
-
for (const c of srtCaptions) {
|
|
69
|
-
if (!c?.url) continue;
|
|
70
|
-
subtitles.push({
|
|
71
|
-
label: c.lanName || c.lan || "Unknown",
|
|
72
|
-
type: getCaptionType(c.url),
|
|
73
|
-
language: c.lan || "",
|
|
74
|
-
url: c.url
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const mkvFiles = data?.mkvData?.files || [];
|
|
80
|
-
for (const f of mkvFiles) {
|
|
81
|
-
if (!f?.url) continue;
|
|
82
|
-
allUrls.push({
|
|
83
|
-
quality: `MKV ${f.size || ""}`.trim(),
|
|
84
|
-
url: f.url,
|
|
85
|
-
type: "mp4",
|
|
86
|
-
headers: HEADERS
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const mkvV2 = data?.mkvV2Data;
|
|
91
|
-
if (mkvV2?.url) {
|
|
92
|
-
allUrls.push({
|
|
93
|
-
quality: `${mkvV2.quality || ""} ${mkvV2.language || ""} ${mkvV2.country || ""} (${mkvV2.size || ""})`.trim(),
|
|
94
|
-
url: mkvV2.url,
|
|
95
|
-
type: "mp4",
|
|
96
|
-
headers: HEADERS
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const mkvV3 = data?.mkvV3Data;
|
|
101
|
-
if (mkvV3?.url) {
|
|
102
|
-
allUrls.push({
|
|
103
|
-
quality: `${mkvV3.quality || ""} ${mkvV3.language || ""} ${mkvV3.country || ""} (${mkvV3.size || ""})`.trim(),
|
|
104
|
-
url: mkvV3.url,
|
|
105
|
-
type: "mp4",
|
|
106
|
-
headers: HEADERS
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return allUrls.length ? { allUrls, subtitles } : null;
|
|
111
|
-
} catch (err) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
1
|
+
import { USER_AGENT } from '../utils/helpers.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = "https://vidvault.ru";
|
|
4
|
+
const HEADERS = {
|
|
5
|
+
"Referer": `${BASE_URL}/`,
|
|
6
|
+
"Origin": BASE_URL,
|
|
7
|
+
"User-Agent": USER_AGENT,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
async function getToken() {
|
|
11
|
+
const res = await fetch(`${BASE_URL}/api/get-token`, {
|
|
12
|
+
method: "GET",
|
|
13
|
+
headers: HEADERS
|
|
14
|
+
});
|
|
15
|
+
const data = await res.json();
|
|
16
|
+
return data.t;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getCaptionType(url) {
|
|
20
|
+
return url.toLowerCase().includes(".vtt") ? "vtt" : "srt";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function getStream(args) {
|
|
24
|
+
const { id, s, e } = args;
|
|
25
|
+
const type = (s != null && e != null) ? "tv" : "movie";
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const token = await getToken();
|
|
29
|
+
|
|
30
|
+
const payload = { type, tmdbId: String(id) };
|
|
31
|
+
if (type === "tv") {
|
|
32
|
+
payload.season = String(s);
|
|
33
|
+
payload.episode = String(e);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const res = await fetch(`${BASE_URL}/api/download-proxy`, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers: {
|
|
39
|
+
...HEADERS,
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
"x-request-token": token
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify(payload)
|
|
44
|
+
});
|
|
45
|
+
const data = await res.json();
|
|
46
|
+
|
|
47
|
+
const allUrls = [];
|
|
48
|
+
const subtitles = [];
|
|
49
|
+
|
|
50
|
+
const mp4 = data?.mp4Data;
|
|
51
|
+
if (mp4) {
|
|
52
|
+
const country = mp4.country || "";
|
|
53
|
+
const lanName = mp4.lanName || "";
|
|
54
|
+
const detailPath = mp4.detailPath || "";
|
|
55
|
+
|
|
56
|
+
const downloads = mp4.downloadInfo?.data?.downloads || [];
|
|
57
|
+
for (const d of downloads) {
|
|
58
|
+
if (!d?.url) continue;
|
|
59
|
+
allUrls.push({
|
|
60
|
+
quality: `${d.resolution}p ${detailPath} ${country} ${lanName}`.trim(),
|
|
61
|
+
url: d.url,
|
|
62
|
+
type: "mp4",
|
|
63
|
+
headers: HEADERS
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const srtCaptions = mp4.downloadInfo?.data?.captions || [];
|
|
68
|
+
for (const c of srtCaptions) {
|
|
69
|
+
if (!c?.url) continue;
|
|
70
|
+
subtitles.push({
|
|
71
|
+
label: c.lanName || c.lan || "Unknown",
|
|
72
|
+
type: getCaptionType(c.url),
|
|
73
|
+
language: c.lan || "",
|
|
74
|
+
url: c.url
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const mkvFiles = data?.mkvData?.files || [];
|
|
80
|
+
for (const f of mkvFiles) {
|
|
81
|
+
if (!f?.url) continue;
|
|
82
|
+
allUrls.push({
|
|
83
|
+
quality: `MKV ${f.size || ""}`.trim(),
|
|
84
|
+
url: f.url,
|
|
85
|
+
type: "mp4",
|
|
86
|
+
headers: HEADERS
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const mkvV2 = data?.mkvV2Data;
|
|
91
|
+
if (mkvV2?.url) {
|
|
92
|
+
allUrls.push({
|
|
93
|
+
quality: `${mkvV2.quality || ""} ${mkvV2.language || ""} ${mkvV2.country || ""} (${mkvV2.size || ""})`.trim(),
|
|
94
|
+
url: mkvV2.url,
|
|
95
|
+
type: "mp4",
|
|
96
|
+
headers: HEADERS
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const mkvV3 = data?.mkvV3Data;
|
|
101
|
+
if (mkvV3?.url) {
|
|
102
|
+
allUrls.push({
|
|
103
|
+
quality: `${mkvV3.quality || ""} ${mkvV3.language || ""} ${mkvV3.country || ""} (${mkvV3.size || ""})`.trim(),
|
|
104
|
+
url: mkvV3.url,
|
|
105
|
+
type: "mp4",
|
|
106
|
+
headers: HEADERS
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return allUrls.length ? { allUrls, subtitles } : null;
|
|
111
|
+
} catch (err) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
114
|
}
|
package/src/sources/vidzee.js
CHANGED
|
@@ -1,106 +1,184 @@
|
|
|
1
|
-
|
|
1
|
+
import { USER_AGENT, fetchJson } from '../utils/helpers.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import { fetchJson, USER_AGENT } from '../utils/helpers.js';
|
|
5
|
-
|
|
6
|
-
const CORE_URL = 'https://core.vidzee.wtf';
|
|
3
|
+
const BASE_URL = 'https://core.vidzee.wtf';
|
|
7
4
|
const PLAYER_URL = 'https://player.vidzee.wtf';
|
|
8
|
-
const
|
|
5
|
+
const SERVICES = ['dcloud', 'ipcloud', 'tik', 'v6:Hindi', '3AHindi'];
|
|
6
|
+
const WASM_B64 = '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';
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
const keyBuf = Buffer.from(KEY, 'utf8');
|
|
12
|
-
const ciphertext = Buffer.from(encryptedBase64, 'base64');
|
|
8
|
+
let wasmInstanceCache = null;
|
|
13
9
|
|
|
10
|
+
async function getWasmInstance() {
|
|
11
|
+
if (wasmInstanceCache) return wasmInstanceCache;
|
|
14
12
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
let dec = decipher.update(ciphertext);
|
|
18
|
-
dec = Buffer.concat([dec, decipher.final()]);
|
|
19
|
-
const text = dec.toString('utf8');
|
|
20
|
-
if (text.startsWith('http') || text.includes('{')) return text;
|
|
21
|
-
} catch { }
|
|
13
|
+
const wasmBuffer = Buffer.from(WASM_B64, 'base64');
|
|
14
|
+
const wasmModule = await WebAssembly.compile(wasmBuffer);
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
+
exports.__unpin(ptr);
|
|
43
|
+
refMap.delete(ptr);
|
|
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);
|
|
32
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) {
|
|
33
94
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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);
|
|
43
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
|
+
}
|
|
44
145
|
return null;
|
|
45
146
|
}
|
|
46
147
|
|
|
47
|
-
export async function getStream(
|
|
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
|
+
|
|
48
153
|
const headers = {
|
|
49
154
|
'User-Agent': USER_AGENT,
|
|
50
|
-
'Accept': 'application/json',
|
|
51
|
-
'Referer': PLAYER_URL
|
|
155
|
+
'Accept': 'application/json, text/plain, */*',
|
|
156
|
+
'Referer': `${PLAYER_URL}/`,
|
|
52
157
|
'Origin': PLAYER_URL,
|
|
53
158
|
...(clientIP && { 'X-Forwarded-For': clientIP })
|
|
54
159
|
};
|
|
55
160
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
const url = isTv
|
|
64
|
-
? `${CORE_URL}/streams/tv/${id}/${s}/${e}?s=${encodeURIComponent(sr)}&e=${e}`
|
|
65
|
-
: `${CORE_URL}/streams/movie/${id}?s=${encodeURIComponent(sr)}&e=1`;
|
|
66
|
-
|
|
67
|
-
const data = await fetchJson(url, { headers, signal: AbortSignal.timeout(6000) });
|
|
68
|
-
|
|
69
|
-
if (data && data.c) {
|
|
70
|
-
const decryptedText = decryptAes(data.c);
|
|
71
|
-
if (decryptedText) {
|
|
72
|
-
let streamUrl = decryptedText;
|
|
73
|
-
let extraHeaders = {};
|
|
74
|
-
|
|
75
|
-
if (decryptedText.startsWith('{')) {
|
|
76
|
-
try {
|
|
77
|
-
const parsed = JSON.parse(decryptedText);
|
|
78
|
-
streamUrl = parsed.url || parsed.link || parsed.file;
|
|
79
|
-
if (parsed.headers) extraHeaders = parsed.headers;
|
|
80
|
-
} catch { }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (streamUrl && streamUrl.startsWith('http')) {
|
|
84
|
-
results.push({
|
|
85
|
-
url: streamUrl,
|
|
86
|
-
server: `VidZee - ${sr}`,
|
|
87
|
-
skipHlsCheck: true,
|
|
88
|
-
headers: {
|
|
89
|
-
'User-Agent': USER_AGENT,
|
|
90
|
-
'Referer': PLAYER_URL,
|
|
91
|
-
'Origin': PLAYER_URL,
|
|
92
|
-
...extraHeaders
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
} catch (err) {
|
|
99
|
-
}
|
|
100
|
-
}
|
|
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
|
+
}
|
|
101
167
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
+
}
|
|
105
177
|
}
|
|
178
|
+
|
|
179
|
+
return allUrls.length ? { allUrls } : null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export async function getSources() {
|
|
183
|
+
return SERVICES.map(s => `VidZee (${s})`);
|
|
106
184
|
}
|
package/src/utils/helpers.js
CHANGED
|
@@ -67,7 +67,7 @@ function cacheGet(cache, key) {
|
|
|
67
67
|
|
|
68
68
|
function cacheSet(cache, key, val, ttl) { cache.set(key, { val, ts: Date.now(), ttl }); }
|
|
69
69
|
|
|
70
|
-
export async function createStreamArgs(source,
|
|
70
|
+
export async function createStreamArgs(source, sdk, id, s, e, clientIP = null) {
|
|
71
71
|
const audio = /dub$/.test(source.key) ? 'dub' : 'sub';
|
|
72
72
|
return {
|
|
73
73
|
id: id,
|
|
@@ -76,7 +76,7 @@ export async function createStreamArgs(source, tmdbApiKey, id, s, e, clientIP =
|
|
|
76
76
|
clientIP: clientIP,
|
|
77
77
|
absoluteBase: '/',
|
|
78
78
|
audio,
|
|
79
|
-
|
|
79
|
+
sdk,
|
|
80
80
|
config: source,
|
|
81
81
|
}
|
|
82
82
|
}
|
package/src/sources/1embed.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { USER_AGENT } from '../utils/helpers.js';
|
|
2
|
-
|
|
3
|
-
const BASE_URL = "https://1embed.cc";
|
|
4
|
-
|
|
5
|
-
const PROVIDERS = [
|
|
6
|
-
{ id: "BUKE", name: "1Embed - BUKE" },
|
|
7
|
-
{ id: "YOTA", name: "1Embed - YOTA" },
|
|
8
|
-
{ id: "NEPT", name: "1Embed - NEPT" },
|
|
9
|
-
{ id: "AZURE", name: "1Embed - AZURE" },
|
|
10
|
-
{ id: "YORU", name: "1Embed - YORU" }
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
let cachedToken = null;
|
|
14
|
-
let tokenExpiresAt = 0;
|
|
15
|
-
|
|
16
|
-
async function getToken() {
|
|
17
|
-
const now = Math.floor(Date.now() / 1000);
|
|
18
|
-
if (cachedToken && tokenExpiresAt > now + 10) return cachedToken;
|
|
19
|
-
try {
|
|
20
|
-
const res = await fetch(`${BASE_URL}/api/token`, { headers: { "Referer": `${BASE_URL}/`, "User-Agent": USER_AGENT, "Accept": "application/json" }, signal: AbortSignal.timeout(10000) });
|
|
21
|
-
if (!res.ok) return null;
|
|
22
|
-
const data = await res.json();
|
|
23
|
-
cachedToken = data.token;
|
|
24
|
-
tokenExpiresAt = data.expiresAt;
|
|
25
|
-
return cachedToken;
|
|
26
|
-
} catch { return null; }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function decodeBsUrl(url) {
|
|
30
|
-
if (!url) return url;
|
|
31
|
-
let target = url;
|
|
32
|
-
if (url.includes('d=')) {
|
|
33
|
-
try {
|
|
34
|
-
const parts = url.split(/[?&]/);
|
|
35
|
-
for (const part of parts) {
|
|
36
|
-
if (part.startsWith('d=')) {
|
|
37
|
-
target = decodeURIComponent(part.substring(2));
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
} catch { }
|
|
42
|
-
}
|
|
43
|
-
if (target.startsWith('bs_')) {
|
|
44
|
-
try {
|
|
45
|
-
const decoded = Buffer.from(target.slice(3), 'base64').toString('utf-8');
|
|
46
|
-
const reversed = decoded.split('').reverse().join('');
|
|
47
|
-
if (reversed.startsWith('http')) return reversed;
|
|
48
|
-
} catch { }
|
|
49
|
-
}
|
|
50
|
-
return url;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function fetchProviderStream(provider, type, id, s, e, token) {
|
|
54
|
-
try {
|
|
55
|
-
const referer = type === "movie" ? `${BASE_URL}/embed/movie/${id}` : `${BASE_URL}/embed/tv/${id}/${s}/${e}`;
|
|
56
|
-
const payload = { type, id: String(id), provider: provider.id };
|
|
57
|
-
if (type === "tv") { payload.season = Number(s); payload.episode = Number(e); }
|
|
58
|
-
const res = await fetch(`${BASE_URL}/api/sources`, {
|
|
59
|
-
method: "POST",
|
|
60
|
-
headers: { "User-Agent": USER_AGENT, "Referer": referer, "Origin": BASE_URL, "Accept": "application/json", "Content-Type": "application/json", "x-bcine-key": token, "X-Requested-With": "XMLHttpRequest" },
|
|
61
|
-
body: JSON.stringify(payload),
|
|
62
|
-
signal: AbortSignal.timeout(15000)
|
|
63
|
-
});
|
|
64
|
-
if (!res.ok) return null;
|
|
65
|
-
const data = await res.json();
|
|
66
|
-
|
|
67
|
-
let rawSources = [];
|
|
68
|
-
if (Array.isArray(data.servers)) rawSources.push(...data.servers);
|
|
69
|
-
if (data.providerResults?.[provider.id]?.sources) rawSources.push(...data.providerResults[provider.id].sources);
|
|
70
|
-
if (data.providerResults?.[provider.id] && Array.isArray(data.providerResults[provider.id])) rawSources.push(...data.providerResults[provider.id]);
|
|
71
|
-
|
|
72
|
-
if (!rawSources.length) return null;
|
|
73
|
-
const results = [];
|
|
74
|
-
for (const src of rawSources) {
|
|
75
|
-
if (typeof src !== 'object' || !src) continue;
|
|
76
|
-
let rawUrl = src.url || src.file || src.link;
|
|
77
|
-
if (typeof rawUrl !== 'string') continue;
|
|
78
|
-
let streamUrl = decodeBsUrl(rawUrl);
|
|
79
|
-
if (streamUrl.startsWith('/')) streamUrl = `${BASE_URL}${streamUrl}`;
|
|
80
|
-
const isWorker = streamUrl.includes('omena-puu') || streamUrl.includes('nocach') || streamUrl.includes('?p=');
|
|
81
|
-
const isHls = src.type === 'hls' || src.type === 'm3u8' || streamUrl.includes('m3u8') || isWorker;
|
|
82
|
-
if (isHls && !streamUrl.includes('m3u8')) streamUrl += streamUrl.includes('?') ? '&format=.m3u8' : '?format=.m3u8';
|
|
83
|
-
const srcHeaders = (src.headers && typeof src.headers === 'object') ? src.headers : {};
|
|
84
|
-
results.push({
|
|
85
|
-
url: streamUrl,
|
|
86
|
-
server: provider.name,
|
|
87
|
-
quality: src.quality || src.label || src.title || "Auto",
|
|
88
|
-
type: isHls ? "hls" : "mp4",
|
|
89
|
-
headers: { "User-Agent": USER_AGENT, "Referer": referer, "Origin": BASE_URL, ...srcHeaders },
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return results;
|
|
93
|
-
} catch {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export async function getStream(args) {
|
|
99
|
-
const { id, s, e, server } = args;
|
|
100
|
-
const type = s != null && e != null ? "tv" : "movie";
|
|
101
|
-
const token = await getToken();
|
|
102
|
-
if (!token) return null;
|
|
103
|
-
let targets = PROVIDERS;
|
|
104
|
-
if (server && server !== 'all') {
|
|
105
|
-
const cleanName = server.replace('1Embed - ', '').toLowerCase();
|
|
106
|
-
targets = PROVIDERS.filter(p => p.id.toLowerCase() === cleanName || p.name.toLowerCase().includes(cleanName));
|
|
107
|
-
if (!targets.length) targets = PROVIDERS;
|
|
108
|
-
}
|
|
109
|
-
const settled = await Promise.allSettled(targets.map(p => fetchProviderStream(p, type, id, s, e, token)));
|
|
110
|
-
const allUrls = [];
|
|
111
|
-
for (const r of settled) if (r.status === 'fulfilled' && r.value) allUrls.push(...r.value);
|
|
112
|
-
return allUrls.length ? { allUrls } : null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export async function getSources() { return PROVIDERS.map(p => p.name); }
|