magmastream 2.9.0-dev.3 → 2.9.0-dev.31
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/README.md +2 -2
- package/dist/index.d.ts +1626 -1103
- package/dist/index.js +8 -0
- package/dist/storage/CollectionPlayerStore.js +77 -0
- package/dist/storage/RedisPlayerStore.js +156 -0
- package/dist/structures/Enums.js +200 -0
- package/dist/structures/Manager.js +473 -316
- package/dist/structures/Node.js +105 -113
- package/dist/structures/Player.js +142 -122
- package/dist/structures/Queue.js +120 -56
- package/dist/structures/RedisQueue.js +309 -0
- package/dist/structures/Rest.js +6 -6
- package/dist/structures/Types.js +3 -0
- package/dist/structures/Utils.js +459 -316
- package/dist/utils/managerCheck.js +15 -12
- package/dist/wrappers/detritus.js +36 -0
- package/dist/wrappers/discord.js.js +29 -0
- package/dist/wrappers/eris.js +29 -0
- package/dist/wrappers/oceanic.js +29 -0
- package/package.json +17 -12
package/dist/structures/Utils.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Structure = exports.AutoPlayUtils = exports.TrackUtils = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const Manager_1 = require("./Manager");
|
|
6
5
|
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
7
6
|
const jsdom_1 = require("jsdom");
|
|
8
7
|
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
8
|
+
const cheerio_1 = tslib_1.__importDefault(require("cheerio"));
|
|
9
|
+
const Enums_1 = require("./Enums");
|
|
9
10
|
/** @hidden */
|
|
10
11
|
const SIZES = ["0", "1", "2", "3", "default", "mqdefault", "hqdefault", "maxresdefault"];
|
|
11
12
|
class TrackUtils {
|
|
@@ -29,27 +30,27 @@ class TrackUtils {
|
|
|
29
30
|
if (!Array.isArray(partial) || !partial.every((str) => typeof str === "string"))
|
|
30
31
|
throw new Error("Provided partial is not an array or not a string array.");
|
|
31
32
|
const defaultProperties = [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
Enums_1.TrackPartial.Track,
|
|
34
|
+
Enums_1.TrackPartial.Title,
|
|
35
|
+
Enums_1.TrackPartial.Identifier,
|
|
36
|
+
Enums_1.TrackPartial.Author,
|
|
37
|
+
Enums_1.TrackPartial.Duration,
|
|
38
|
+
Enums_1.TrackPartial.Isrc,
|
|
39
|
+
Enums_1.TrackPartial.IsSeekable,
|
|
40
|
+
Enums_1.TrackPartial.IsStream,
|
|
41
|
+
Enums_1.TrackPartial.Uri,
|
|
42
|
+
Enums_1.TrackPartial.ArtworkUrl,
|
|
43
|
+
Enums_1.TrackPartial.SourceName,
|
|
44
|
+
Enums_1.TrackPartial.ThumbNail,
|
|
45
|
+
Enums_1.TrackPartial.Requester,
|
|
46
|
+
Enums_1.TrackPartial.PluginInfo,
|
|
47
|
+
Enums_1.TrackPartial.CustomData,
|
|
47
48
|
];
|
|
48
49
|
/** The array of property names that will be removed from the Track class */
|
|
49
50
|
this.trackPartial = Array.from(new Set([...defaultProperties, ...partial]));
|
|
50
51
|
/** Make sure that the "track" property is always included */
|
|
51
|
-
if (!this.trackPartial.includes(
|
|
52
|
-
this.trackPartial.unshift(
|
|
52
|
+
if (!this.trackPartial.includes(Enums_1.TrackPartial.Track))
|
|
53
|
+
this.trackPartial.unshift(Enums_1.TrackPartial.Track);
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
55
56
|
* Checks if the provided argument is a valid Track.
|
|
@@ -143,58 +144,42 @@ class AutoPlayUtils {
|
|
|
143
144
|
throw new Error("AutoPlayUtils.init() requires a valid Manager instance.");
|
|
144
145
|
this.manager = manager;
|
|
145
146
|
}
|
|
146
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Gets recommended tracks for the given track.
|
|
149
|
+
* @param track The track to get recommended tracks for.
|
|
150
|
+
* @returns An array of recommended tracks.
|
|
151
|
+
*/
|
|
152
|
+
static async getRecommendedTracks(track) {
|
|
147
153
|
const node = this.manager.useableNode;
|
|
148
154
|
if (!node) {
|
|
149
155
|
throw new Error("No available nodes.");
|
|
150
156
|
}
|
|
151
|
-
if (!player.isAutoplay) {
|
|
152
|
-
return [];
|
|
153
|
-
}
|
|
154
|
-
if (attempt >= player.autoplayTries) {
|
|
155
|
-
return [];
|
|
156
|
-
}
|
|
157
|
-
if (!player.queue.previous.length) {
|
|
158
|
-
return [];
|
|
159
|
-
}
|
|
160
157
|
const apiKey = this.manager.options.lastFmApiKey;
|
|
161
158
|
const enabledSources = node.info.sourceManagers;
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
[Manager_1.SearchPlatform.VKMusic]: "vkmusic",
|
|
173
|
-
[Manager_1.SearchPlatform.YouTube]: "youtube",
|
|
174
|
-
[Manager_1.SearchPlatform.YouTubeMusic]: "youtube",
|
|
175
|
-
};
|
|
176
|
-
const mappedPlatform = platformMapping[autoPlaySearchPlatform];
|
|
177
|
-
// Last attempt fallback to YouTube
|
|
178
|
-
if (attempt === player.autoplayTries - 1 && player.autoplayTries > 1 && enabledSources.includes("youtube")) {
|
|
179
|
-
return await this.getRecommendedTracksFromYouTube(track);
|
|
180
|
-
}
|
|
181
|
-
// Check if the preferred autoplay platform is supported and enabled
|
|
182
|
-
if (mappedPlatform && supportedPlatforms.includes(mappedPlatform) && enabledSources.includes(mappedPlatform)) {
|
|
183
|
-
return await this.getRecommendedTracksFromSource(track, mappedPlatform);
|
|
159
|
+
const autoPlaySearchPlatforms = this.manager.options.autoPlaySearchPlatforms;
|
|
160
|
+
// Iterate over autoplay platforms in order of priority
|
|
161
|
+
for (const platform of autoPlaySearchPlatforms) {
|
|
162
|
+
if (enabledSources.includes(platform)) {
|
|
163
|
+
const recommendedTracks = await this.getRecommendedTracksFromSource(track, platform);
|
|
164
|
+
// If tracks are found, return them immediately
|
|
165
|
+
if (recommendedTracks.length > 0) {
|
|
166
|
+
return recommendedTracks;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
184
169
|
}
|
|
185
170
|
// Check if Last.fm API is available
|
|
186
171
|
if (apiKey) {
|
|
187
172
|
return await this.getRecommendedTracksFromLastFm(track, apiKey);
|
|
188
173
|
}
|
|
189
|
-
// Fallback to YouTube if all else fails
|
|
190
|
-
if (enabledSources.includes("youtube")) {
|
|
191
|
-
return await this.getRecommendedTracksFromYouTube(track);
|
|
192
|
-
}
|
|
193
174
|
return [];
|
|
194
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Gets recommended tracks from Last.fm for the given track.
|
|
178
|
+
* @param track The track to get recommended tracks for.
|
|
179
|
+
* @param apiKey The API key for Last.fm.
|
|
180
|
+
* @returns An array of recommended tracks.
|
|
181
|
+
*/
|
|
195
182
|
static async getRecommendedTracksFromLastFm(track, apiKey) {
|
|
196
|
-
const enabledSources = this.manager.useableNode.info.sourceManagers;
|
|
197
|
-
const selectedSource = this.selectPlatform(enabledSources);
|
|
198
183
|
let { author: artist } = track;
|
|
199
184
|
const { title } = track;
|
|
200
185
|
if (!artist || !title) {
|
|
@@ -206,8 +191,8 @@ class AutoPlayUtils {
|
|
|
206
191
|
return [];
|
|
207
192
|
}
|
|
208
193
|
const randomTrack = response.data.toptracks.track[Math.floor(Math.random() * response.data.toptracks.track.length)];
|
|
209
|
-
const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source:
|
|
210
|
-
if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
|
|
194
|
+
const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: this.manager.options.defaultSearchPlatform }, track.requester);
|
|
195
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
211
196
|
return [];
|
|
212
197
|
}
|
|
213
198
|
const filteredTracks = res.tracks.filter((t) => t.uri !== track.uri);
|
|
@@ -233,7 +218,7 @@ class AutoPlayUtils {
|
|
|
233
218
|
response = await axios_1.default.get(url);
|
|
234
219
|
}
|
|
235
220
|
catch (error) {
|
|
236
|
-
console.
|
|
221
|
+
console.error("[AutoPlay] Error fetching similar tracks from Last.fm:", error);
|
|
237
222
|
return [];
|
|
238
223
|
}
|
|
239
224
|
if (response.data.error || !response.data.similartracks?.track?.length) {
|
|
@@ -244,8 +229,8 @@ class AutoPlayUtils {
|
|
|
244
229
|
return [];
|
|
245
230
|
}
|
|
246
231
|
const randomTrack = retryResponse.data.toptracks.track[Math.floor(Math.random() * retryResponse.data.toptracks.track.length)];
|
|
247
|
-
const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source:
|
|
248
|
-
if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
|
|
232
|
+
const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: this.manager.options.defaultSearchPlatform }, track.requester);
|
|
233
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
249
234
|
return [];
|
|
250
235
|
}
|
|
251
236
|
const filteredTracks = res.tracks.filter((t) => t.uri !== track.uri);
|
|
@@ -258,27 +243,127 @@ class AutoPlayUtils {
|
|
|
258
243
|
if (!randomTrack) {
|
|
259
244
|
return [];
|
|
260
245
|
}
|
|
261
|
-
const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source:
|
|
262
|
-
if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
|
|
246
|
+
const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: this.manager.options.defaultSearchPlatform }, track.requester);
|
|
247
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
263
248
|
return [];
|
|
264
249
|
}
|
|
265
|
-
if (res.loadType === LoadTypes.Playlist)
|
|
250
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist)
|
|
266
251
|
res.tracks = res.playlist.tracks;
|
|
267
252
|
if (!res.tracks.length) {
|
|
268
253
|
return [];
|
|
269
254
|
}
|
|
270
255
|
return res.tracks;
|
|
271
256
|
}
|
|
272
|
-
|
|
273
|
-
|
|
257
|
+
/**
|
|
258
|
+
* Gets recommended tracks from the given source.
|
|
259
|
+
* @param track The track to get recommended tracks for.
|
|
260
|
+
* @param platform The source to get recommended tracks from.
|
|
261
|
+
* @returns An array of recommended tracks.
|
|
262
|
+
*/
|
|
263
|
+
static async getRecommendedTracksFromSource(track, platform) {
|
|
264
|
+
switch (platform) {
|
|
274
265
|
case "spotify":
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
266
|
+
{
|
|
267
|
+
try {
|
|
268
|
+
if (!track.uri.includes("spotify")) {
|
|
269
|
+
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.Spotify }, track.requester);
|
|
270
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
274
|
+
res.tracks = res.playlist.tracks;
|
|
275
|
+
}
|
|
276
|
+
if (!res.tracks.length) {
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
track = res.tracks[0];
|
|
280
|
+
}
|
|
281
|
+
const periodMs = 30000;
|
|
282
|
+
async function getSpotifyTotpParams() {
|
|
283
|
+
try {
|
|
284
|
+
const secretBuffer = await AutoPlayUtils.fetchSecretArray();
|
|
285
|
+
const transformedSecret = AutoPlayUtils.transformSecret(secretBuffer);
|
|
286
|
+
const totp = AutoPlayUtils.generateTotp(transformedSecret);
|
|
287
|
+
const timestamp = Math.floor(Date.now() / periodMs) * periodMs;
|
|
288
|
+
const params = {
|
|
289
|
+
reason: "transport",
|
|
290
|
+
productType: "embed",
|
|
291
|
+
totp,
|
|
292
|
+
totpVer: 5,
|
|
293
|
+
ts: timestamp,
|
|
294
|
+
};
|
|
295
|
+
return params;
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
console.error("Failed to generate Spotify TOTP params:", error);
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
let body;
|
|
303
|
+
try {
|
|
304
|
+
const params = await getSpotifyTotpParams();
|
|
305
|
+
const response = await axios_1.default.get("https://open.spotify.com/get_access_token", {
|
|
306
|
+
params,
|
|
307
|
+
headers: {
|
|
308
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.6998.178 Spotify/1.2.65.255 Safari/537.36",
|
|
309
|
+
"App-Platform": "WebPlayer",
|
|
310
|
+
Referer: "https://open.spotify.com/",
|
|
311
|
+
Origin: "https://open.spotify.com",
|
|
312
|
+
"Accept-Language": "en",
|
|
313
|
+
"Content-Type": "application/json",
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
body = response.data;
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
console.error("[AutoPlay] Failed to get spotify access token:", error.response?.status);
|
|
279
320
|
return [];
|
|
280
321
|
}
|
|
281
|
-
|
|
322
|
+
let json;
|
|
323
|
+
try {
|
|
324
|
+
const response = await axios_1.default.get(`https://api.spotify.com/v1/recommendations`, {
|
|
325
|
+
params: { limit: 10, seed_tracks: track.identifier },
|
|
326
|
+
headers: {
|
|
327
|
+
Authorization: `Bearer ${body.accessToken}`,
|
|
328
|
+
"Content-Type": "application/json",
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
json = response.data;
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
console.error("[AutoPlay] Failed to fetch spotify recommendations:", error.response?.status);
|
|
335
|
+
return [];
|
|
336
|
+
}
|
|
337
|
+
if (!json.tracks || !json.tracks.length) {
|
|
338
|
+
return [];
|
|
339
|
+
}
|
|
340
|
+
const recommendedTrackId = json.tracks[Math.floor(Math.random() * json.tracks.length)].id;
|
|
341
|
+
const res = await this.manager.search({ query: `https://open.spotify.com/track/${recommendedTrackId}`, source: Enums_1.SearchPlatform.Spotify }, track.requester);
|
|
342
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
343
|
+
return [];
|
|
344
|
+
}
|
|
345
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
346
|
+
res.tracks = res.playlist.tracks;
|
|
347
|
+
}
|
|
348
|
+
if (!res.tracks.length) {
|
|
349
|
+
return [];
|
|
350
|
+
}
|
|
351
|
+
return res.tracks;
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
console.error("[AutoPlay] Unexpected spotify error:", error.message || error);
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
break;
|
|
359
|
+
case "deezer":
|
|
360
|
+
{
|
|
361
|
+
if (!track.uri.includes("deezer")) {
|
|
362
|
+
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.Deezer }, track.requester);
|
|
363
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
282
367
|
res.tracks = res.playlist.tracks;
|
|
283
368
|
}
|
|
284
369
|
if (!res.tracks.length) {
|
|
@@ -286,253 +371,353 @@ class AutoPlayUtils {
|
|
|
286
371
|
}
|
|
287
372
|
track = res.tracks[0];
|
|
288
373
|
}
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
function generateTotp() {
|
|
294
|
-
const counter = Math.floor(Date.now() / 30000);
|
|
295
|
-
const counterBuffer = Buffer.alloc(8);
|
|
296
|
-
counterBuffer.writeBigInt64BE(BigInt(counter));
|
|
297
|
-
hmac.update(counterBuffer);
|
|
298
|
-
const hmacResult = hmac.digest();
|
|
299
|
-
const offset = hmacResult[hmacResult.length - 1] & 15;
|
|
300
|
-
const truncatedValue = ((hmacResult[offset] & 127) << 24) | ((hmacResult[offset + 1] & 255) << 16) | ((hmacResult[offset + 2] & 255) << 8) | (hmacResult[offset + 3] & 255);
|
|
301
|
-
const totp = (truncatedValue % 1000000).toString().padStart(6, "0");
|
|
302
|
-
return [totp, counter * 30000];
|
|
303
|
-
}
|
|
304
|
-
const [totp, timestamp] = generateTotp();
|
|
305
|
-
const params = {
|
|
306
|
-
reason: "transport",
|
|
307
|
-
productType: "embed",
|
|
308
|
-
totp: totp,
|
|
309
|
-
totpVer: 5,
|
|
310
|
-
ts: timestamp,
|
|
311
|
-
};
|
|
312
|
-
let body;
|
|
313
|
-
try {
|
|
314
|
-
const response = await axios_1.default.get("https://open.spotify.com/get_access_token", { params });
|
|
315
|
-
body = response.data;
|
|
374
|
+
const identifier = `dzrec:${track.identifier}`;
|
|
375
|
+
const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
|
|
376
|
+
if (!recommendedResult) {
|
|
377
|
+
return [];
|
|
316
378
|
}
|
|
317
|
-
|
|
318
|
-
|
|
379
|
+
let tracks = [];
|
|
380
|
+
let playlist = null;
|
|
381
|
+
const requester = track.requester;
|
|
382
|
+
switch (recommendedResult.loadType) {
|
|
383
|
+
case Enums_1.LoadTypes.Search:
|
|
384
|
+
tracks = recommendedResult.data.map((track) => TrackUtils.build(track, requester));
|
|
385
|
+
break;
|
|
386
|
+
case Enums_1.LoadTypes.Track:
|
|
387
|
+
tracks = [TrackUtils.build(recommendedResult.data, requester)];
|
|
388
|
+
break;
|
|
389
|
+
case Enums_1.LoadTypes.Playlist: {
|
|
390
|
+
const playlistData = recommendedResult.data;
|
|
391
|
+
tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
|
|
392
|
+
playlist = {
|
|
393
|
+
name: playlistData.info.name,
|
|
394
|
+
playlistInfo: playlistData.pluginInfo,
|
|
395
|
+
requester: requester,
|
|
396
|
+
tracks,
|
|
397
|
+
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
398
|
+
};
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const result = { loadType: recommendedResult.loadType, tracks, playlist };
|
|
403
|
+
if (result.loadType === Enums_1.LoadTypes.Empty || result.loadType === Enums_1.LoadTypes.Error) {
|
|
404
|
+
return [];
|
|
405
|
+
}
|
|
406
|
+
if (result.loadType === Enums_1.LoadTypes.Playlist) {
|
|
407
|
+
result.tracks = result.playlist.tracks;
|
|
408
|
+
}
|
|
409
|
+
if (!result.tracks.length) {
|
|
319
410
|
return [];
|
|
320
411
|
}
|
|
321
|
-
|
|
412
|
+
return result.tracks;
|
|
413
|
+
}
|
|
414
|
+
break;
|
|
415
|
+
case "soundcloud":
|
|
416
|
+
{
|
|
417
|
+
if (!track.uri.includes("soundcloud")) {
|
|
418
|
+
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.SoundCloud }, track.requester);
|
|
419
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
420
|
+
return [];
|
|
421
|
+
}
|
|
422
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
423
|
+
res.tracks = res.playlist.tracks;
|
|
424
|
+
}
|
|
425
|
+
if (!res.tracks.length) {
|
|
426
|
+
return [];
|
|
427
|
+
}
|
|
428
|
+
track = res.tracks[0];
|
|
429
|
+
}
|
|
322
430
|
try {
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
Authorization: `Bearer ${body.accessToken}`,
|
|
327
|
-
"Content-Type": "application/json",
|
|
328
|
-
},
|
|
431
|
+
const recommendedRes = await axios_1.default.get(`${track.uri}/recommended`).catch((err) => {
|
|
432
|
+
console.error(`[AutoPlay] Failed to fetch SoundCloud recommendations. Status: ${err.response?.status || "Unknown"}`, err.message);
|
|
433
|
+
return null;
|
|
329
434
|
});
|
|
330
|
-
|
|
435
|
+
if (!recommendedRes) {
|
|
436
|
+
return [];
|
|
437
|
+
}
|
|
438
|
+
const html = recommendedRes.data;
|
|
439
|
+
const dom = new jsdom_1.JSDOM(html);
|
|
440
|
+
const document = dom.window.document;
|
|
441
|
+
const secondNoscript = document.querySelectorAll("noscript")[1];
|
|
442
|
+
const sectionElement = secondNoscript.querySelector("section");
|
|
443
|
+
const articleElements = sectionElement.querySelectorAll("article");
|
|
444
|
+
if (!articleElements || articleElements.length === 0) {
|
|
445
|
+
return [];
|
|
446
|
+
}
|
|
447
|
+
const urls = Array.from(articleElements)
|
|
448
|
+
.map((articleElement) => {
|
|
449
|
+
const h2Element = articleElement.querySelector('h2[itemprop="name"]');
|
|
450
|
+
const aElement = h2Element?.querySelector('a[itemprop="url"]');
|
|
451
|
+
return aElement ? `https://soundcloud.com${aElement.getAttribute("href")}` : null;
|
|
452
|
+
})
|
|
453
|
+
.filter(Boolean);
|
|
454
|
+
if (!urls.length) {
|
|
455
|
+
return [];
|
|
456
|
+
}
|
|
457
|
+
const randomUrl = urls[Math.floor(Math.random() * urls.length)];
|
|
458
|
+
const res = await this.manager.search({ query: randomUrl, source: Enums_1.SearchPlatform.SoundCloud }, track.requester);
|
|
459
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
460
|
+
return [];
|
|
461
|
+
}
|
|
462
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
463
|
+
res.tracks = res.playlist.tracks;
|
|
464
|
+
}
|
|
465
|
+
if (!res.tracks.length) {
|
|
466
|
+
return [];
|
|
467
|
+
}
|
|
468
|
+
return res.tracks;
|
|
331
469
|
}
|
|
332
470
|
catch (error) {
|
|
333
|
-
console.error("[AutoPlay]
|
|
471
|
+
console.error("[AutoPlay] Error occurred while fetching soundcloud recommendations:", error);
|
|
334
472
|
return [];
|
|
335
473
|
}
|
|
336
|
-
|
|
474
|
+
}
|
|
475
|
+
break;
|
|
476
|
+
case "youtube":
|
|
477
|
+
{
|
|
478
|
+
const hasYouTubeURL = ["youtube.com", "youtu.be"].some((url) => track.uri.includes(url));
|
|
479
|
+
let videoID = null;
|
|
480
|
+
if (hasYouTubeURL) {
|
|
481
|
+
videoID = track.uri.split("=").pop();
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
const searchResult = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.YouTube }, track.requester);
|
|
485
|
+
videoID = searchResult.tracks[0]?.uri.split("=").pop();
|
|
486
|
+
}
|
|
487
|
+
if (!videoID) {
|
|
337
488
|
return [];
|
|
338
489
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
490
|
+
let randomIndex;
|
|
491
|
+
let searchURI;
|
|
492
|
+
do {
|
|
493
|
+
randomIndex = Math.floor(Math.random() * 23) + 2;
|
|
494
|
+
searchURI = `https://www.youtube.com/watch?v=${videoID}&list=RD${videoID}&index=${randomIndex}`;
|
|
495
|
+
} while (track.uri.includes(searchURI));
|
|
496
|
+
const res = await this.manager.search({ query: searchURI, source: Enums_1.SearchPlatform.YouTube }, track.requester);
|
|
497
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
342
498
|
return [];
|
|
343
499
|
}
|
|
344
|
-
|
|
345
|
-
|
|
500
|
+
const filteredTracks = res.tracks.filter((t) => t.uri !== track.uri);
|
|
501
|
+
return filteredTracks;
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
504
|
+
case "tidal":
|
|
505
|
+
{
|
|
506
|
+
if (!track.uri.includes("tidal")) {
|
|
507
|
+
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.Tidal }, track.requester);
|
|
508
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
509
|
+
return [];
|
|
510
|
+
}
|
|
511
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
512
|
+
res.tracks = res.playlist.tracks;
|
|
513
|
+
}
|
|
514
|
+
if (!res.tracks.length) {
|
|
515
|
+
return [];
|
|
516
|
+
}
|
|
517
|
+
track = res.tracks[0];
|
|
346
518
|
}
|
|
347
|
-
|
|
519
|
+
const identifier = `tdrec:${track.identifier}`;
|
|
520
|
+
const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
|
|
521
|
+
if (!recommendedResult) {
|
|
348
522
|
return [];
|
|
349
523
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
524
|
+
let tracks = [];
|
|
525
|
+
let playlist = null;
|
|
526
|
+
const requester = track.requester;
|
|
527
|
+
switch (recommendedResult.loadType) {
|
|
528
|
+
case Enums_1.LoadTypes.Search:
|
|
529
|
+
tracks = recommendedResult.data.map((track) => TrackUtils.build(track, requester));
|
|
530
|
+
break;
|
|
531
|
+
case Enums_1.LoadTypes.Track:
|
|
532
|
+
tracks = [TrackUtils.build(recommendedResult.data, requester)];
|
|
533
|
+
break;
|
|
534
|
+
case Enums_1.LoadTypes.Playlist: {
|
|
535
|
+
const playlistData = recommendedResult.data;
|
|
536
|
+
tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
|
|
537
|
+
playlist = {
|
|
538
|
+
name: playlistData.info.name,
|
|
539
|
+
playlistInfo: playlistData.pluginInfo,
|
|
540
|
+
requester: requester,
|
|
541
|
+
tracks,
|
|
542
|
+
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
543
|
+
};
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
const result = { loadType: recommendedResult.loadType, tracks, playlist };
|
|
548
|
+
if (result.loadType === Enums_1.LoadTypes.Empty || result.loadType === Enums_1.LoadTypes.Error) {
|
|
360
549
|
return [];
|
|
361
550
|
}
|
|
362
|
-
if (
|
|
363
|
-
|
|
551
|
+
if (result.loadType === Enums_1.LoadTypes.Playlist) {
|
|
552
|
+
result.tracks = result.playlist.tracks;
|
|
364
553
|
}
|
|
365
|
-
if (!
|
|
554
|
+
if (!result.tracks.length) {
|
|
366
555
|
return [];
|
|
367
556
|
}
|
|
368
|
-
|
|
557
|
+
return result.tracks;
|
|
369
558
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
case LoadTypes.Playlist: {
|
|
386
|
-
const playlistData = recommendedResult.data;
|
|
387
|
-
tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
|
|
388
|
-
playlist = {
|
|
389
|
-
name: playlistData.info.name,
|
|
390
|
-
playlistInfo: playlistData.pluginInfo,
|
|
391
|
-
requester: requester,
|
|
392
|
-
tracks,
|
|
393
|
-
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
394
|
-
};
|
|
395
|
-
break;
|
|
559
|
+
break;
|
|
560
|
+
case "vkmusic":
|
|
561
|
+
{
|
|
562
|
+
if (!track.uri.includes("vk.com") && !track.uri.includes("vk.ru")) {
|
|
563
|
+
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.VKMusic }, track.requester);
|
|
564
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
568
|
+
res.tracks = res.playlist.tracks;
|
|
569
|
+
}
|
|
570
|
+
if (!res.tracks.length) {
|
|
571
|
+
return [];
|
|
572
|
+
}
|
|
573
|
+
track = res.tracks[0];
|
|
396
574
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return [];
|
|
401
|
-
}
|
|
402
|
-
if (result.loadType === LoadTypes.Playlist) {
|
|
403
|
-
result.tracks = result.playlist.tracks;
|
|
404
|
-
}
|
|
405
|
-
if (!result.tracks.length) {
|
|
406
|
-
return [];
|
|
407
|
-
}
|
|
408
|
-
return result.tracks;
|
|
409
|
-
case "soundcloud":
|
|
410
|
-
if (!track.uri.includes("soundcloud")) {
|
|
411
|
-
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.SoundCloud }, track.requester);
|
|
412
|
-
if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
|
|
575
|
+
const identifier = `vkrec:${track.identifier}`;
|
|
576
|
+
const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
|
|
577
|
+
if (!recommendedResult) {
|
|
413
578
|
return [];
|
|
414
579
|
}
|
|
415
|
-
|
|
416
|
-
|
|
580
|
+
let tracks = [];
|
|
581
|
+
let playlist = null;
|
|
582
|
+
const requester = track.requester;
|
|
583
|
+
switch (recommendedResult.loadType) {
|
|
584
|
+
case Enums_1.LoadTypes.Search:
|
|
585
|
+
tracks = recommendedResult.data.map((track) => TrackUtils.build(track, requester));
|
|
586
|
+
break;
|
|
587
|
+
case Enums_1.LoadTypes.Track:
|
|
588
|
+
tracks = [TrackUtils.build(recommendedResult.data, requester)];
|
|
589
|
+
break;
|
|
590
|
+
case Enums_1.LoadTypes.Playlist: {
|
|
591
|
+
const playlistData = recommendedResult.data;
|
|
592
|
+
tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
|
|
593
|
+
playlist = {
|
|
594
|
+
name: playlistData.info.name,
|
|
595
|
+
playlistInfo: playlistData.pluginInfo,
|
|
596
|
+
requester: requester,
|
|
597
|
+
tracks,
|
|
598
|
+
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
599
|
+
};
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
417
602
|
}
|
|
418
|
-
|
|
603
|
+
const result = { loadType: recommendedResult.loadType, tracks, playlist };
|
|
604
|
+
if (result.loadType === Enums_1.LoadTypes.Empty || result.loadType === Enums_1.LoadTypes.Error) {
|
|
419
605
|
return [];
|
|
420
606
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
try {
|
|
424
|
-
const recommendedRes = await axios_1.default.get(`${track.uri}/recommended`).catch((err) => {
|
|
425
|
-
console.error(`[AutoPlay] Failed to fetch SoundCloud recommendations. Status: ${err.response?.status || "Unknown"}`, err.message);
|
|
426
|
-
return null;
|
|
427
|
-
});
|
|
428
|
-
if (!recommendedRes) {
|
|
429
|
-
return [];
|
|
607
|
+
if (result.loadType === Enums_1.LoadTypes.Playlist) {
|
|
608
|
+
result.tracks = result.playlist.tracks;
|
|
430
609
|
}
|
|
431
|
-
|
|
432
|
-
const dom = new jsdom_1.JSDOM(html);
|
|
433
|
-
const document = dom.window.document;
|
|
434
|
-
const secondNoscript = document.querySelectorAll("noscript")[1];
|
|
435
|
-
const sectionElement = secondNoscript.querySelector("section");
|
|
436
|
-
const articleElements = sectionElement.querySelectorAll("article");
|
|
437
|
-
if (!articleElements || articleElements.length === 0) {
|
|
610
|
+
if (!result.tracks.length) {
|
|
438
611
|
return [];
|
|
439
612
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
.
|
|
447
|
-
|
|
613
|
+
return result.tracks;
|
|
614
|
+
}
|
|
615
|
+
break;
|
|
616
|
+
case "qobuz":
|
|
617
|
+
{
|
|
618
|
+
if (!track.uri.includes("qobuz.com")) {
|
|
619
|
+
const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Enums_1.SearchPlatform.Qobuz }, track.requester);
|
|
620
|
+
if (res.loadType === Enums_1.LoadTypes.Empty || res.loadType === Enums_1.LoadTypes.Error) {
|
|
621
|
+
return [];
|
|
622
|
+
}
|
|
623
|
+
if (res.loadType === Enums_1.LoadTypes.Playlist) {
|
|
624
|
+
res.tracks = res.playlist.tracks;
|
|
625
|
+
}
|
|
626
|
+
if (!res.tracks.length) {
|
|
627
|
+
return [];
|
|
628
|
+
}
|
|
629
|
+
track = res.tracks[0];
|
|
630
|
+
}
|
|
631
|
+
const identifier = `qbrec:${track.identifier}`;
|
|
632
|
+
const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
|
|
633
|
+
if (!recommendedResult) {
|
|
448
634
|
return [];
|
|
449
635
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
636
|
+
let tracks = [];
|
|
637
|
+
let playlist = null;
|
|
638
|
+
const requester = track.requester;
|
|
639
|
+
switch (recommendedResult.loadType) {
|
|
640
|
+
case Enums_1.LoadTypes.Search:
|
|
641
|
+
tracks = recommendedResult.data.map((track) => TrackUtils.build(track, requester));
|
|
642
|
+
break;
|
|
643
|
+
case Enums_1.LoadTypes.Track:
|
|
644
|
+
tracks = [TrackUtils.build(recommendedResult.data, requester)];
|
|
645
|
+
break;
|
|
646
|
+
case Enums_1.LoadTypes.Playlist: {
|
|
647
|
+
const playlistData = recommendedResult.data;
|
|
648
|
+
tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
|
|
649
|
+
playlist = {
|
|
650
|
+
name: playlistData.info.name,
|
|
651
|
+
playlistInfo: playlistData.pluginInfo,
|
|
652
|
+
requester: requester,
|
|
653
|
+
tracks,
|
|
654
|
+
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
655
|
+
};
|
|
656
|
+
break;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const result = { loadType: recommendedResult.loadType, tracks, playlist };
|
|
660
|
+
if (result.loadType === Enums_1.LoadTypes.Empty || result.loadType === Enums_1.LoadTypes.Error) {
|
|
453
661
|
return [];
|
|
454
662
|
}
|
|
455
|
-
if (
|
|
456
|
-
|
|
663
|
+
if (result.loadType === Enums_1.LoadTypes.Playlist) {
|
|
664
|
+
result.tracks = result.playlist.tracks;
|
|
457
665
|
}
|
|
458
|
-
if (!
|
|
666
|
+
if (!result.tracks.length) {
|
|
459
667
|
return [];
|
|
460
668
|
}
|
|
461
|
-
return
|
|
462
|
-
}
|
|
463
|
-
catch (error) {
|
|
464
|
-
console.error("[AutoPlay] Error occurred while fetching recommendations:", error);
|
|
465
|
-
return [];
|
|
669
|
+
return result.tracks;
|
|
466
670
|
}
|
|
467
|
-
|
|
468
|
-
return this.getRecommendedTracksFromYouTube(track);
|
|
671
|
+
break;
|
|
469
672
|
default:
|
|
470
673
|
return [];
|
|
471
674
|
}
|
|
472
675
|
}
|
|
473
|
-
static async
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
return filteredTracks;
|
|
676
|
+
static async fetchSecretArray() {
|
|
677
|
+
// Step 1: Get Spotify homepage HTML
|
|
678
|
+
const homepageRes = await axios_1.default.get("https://open.spotify.com/");
|
|
679
|
+
const $ = cheerio_1.default.load(homepageRes.data);
|
|
680
|
+
// Step 2: Find script URL with "mobile-web-player" but not "vendor"
|
|
681
|
+
const scriptUrl = $("script[src]")
|
|
682
|
+
.map((_, el) => $(el).attr("src"))
|
|
683
|
+
.get()
|
|
684
|
+
.find((src) => src.includes("mobile-web-player") && !src.includes("vendor"));
|
|
685
|
+
if (!scriptUrl)
|
|
686
|
+
throw new Error("Secret script not found");
|
|
687
|
+
// Full URL fix (if needed)
|
|
688
|
+
const fullScriptUrl = scriptUrl.startsWith("http") ? scriptUrl : "https://open.spotify.com" + scriptUrl;
|
|
689
|
+
// Step 3: Fetch the script content
|
|
690
|
+
const scriptRes = await axios_1.default.get(fullScriptUrl);
|
|
691
|
+
const scriptContent = scriptRes.data;
|
|
692
|
+
// Step 4: Extract secret array using regex
|
|
693
|
+
const secretPattern = /\(\[(\d+(?:,\d+)+)]\)/;
|
|
694
|
+
const match = secretPattern.exec(scriptContent);
|
|
695
|
+
if (!match)
|
|
696
|
+
throw new Error("Secret array not found in script");
|
|
697
|
+
// Parse the secret array into bytes
|
|
698
|
+
const secretArray = match[1].split(",").map((n) => parseInt(n.trim(), 10));
|
|
699
|
+
return Buffer.from(secretArray);
|
|
498
700
|
}
|
|
499
|
-
static
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
[
|
|
503
|
-
[Manager_1.SearchPlatform.Bandcamp]: "bandcamp",
|
|
504
|
-
[Manager_1.SearchPlatform.Deezer]: "deezer",
|
|
505
|
-
[Manager_1.SearchPlatform.Jiosaavn]: "jiosaavn",
|
|
506
|
-
[Manager_1.SearchPlatform.SoundCloud]: "soundcloud",
|
|
507
|
-
[Manager_1.SearchPlatform.Spotify]: "spotify",
|
|
508
|
-
[Manager_1.SearchPlatform.Tidal]: "tidal",
|
|
509
|
-
[Manager_1.SearchPlatform.VKMusic]: "vkmusic",
|
|
510
|
-
[Manager_1.SearchPlatform.YouTube]: "youtube",
|
|
511
|
-
[Manager_1.SearchPlatform.YouTubeMusic]: "youtube",
|
|
512
|
-
};
|
|
513
|
-
// Try the autoPlaySearchPlatform first
|
|
514
|
-
if (enabledSources.includes(platformMapping[autoPlaySearchPlatform])) {
|
|
515
|
-
return autoPlaySearchPlatform;
|
|
701
|
+
static transformSecret(buffer) {
|
|
702
|
+
const transformed = Buffer.alloc(buffer.length);
|
|
703
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
704
|
+
transformed[i] = buffer[i] ^ ((i % 33) + 9);
|
|
516
705
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
];
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
return platform;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
return null;
|
|
706
|
+
return transformed;
|
|
707
|
+
}
|
|
708
|
+
static generateTotp(secretBuffer) {
|
|
709
|
+
const period = 30; // seconds
|
|
710
|
+
const digits = 6;
|
|
711
|
+
const counter = Math.floor(Date.now() / 1000 / period);
|
|
712
|
+
const counterBuffer = Buffer.alloc(8);
|
|
713
|
+
counterBuffer.writeBigInt64BE(BigInt(counter));
|
|
714
|
+
const hmac = crypto_1.default.createHmac("sha1", secretBuffer);
|
|
715
|
+
hmac.update(counterBuffer);
|
|
716
|
+
const hmacResult = hmac.digest();
|
|
717
|
+
const offset = hmacResult[hmacResult.length - 1] & 0x0f;
|
|
718
|
+
const binary = ((hmacResult[offset] & 0x7f) << 24) | ((hmacResult[offset + 1] & 0xff) << 16) | ((hmacResult[offset + 2] & 0xff) << 8) | (hmacResult[offset + 3] & 0xff);
|
|
719
|
+
const otp = binary % 10 ** digits;
|
|
720
|
+
return otp.toString().padStart(digits, "0");
|
|
536
721
|
}
|
|
537
722
|
}
|
|
538
723
|
exports.AutoPlayUtils = AutoPlayUtils;
|
|
@@ -572,45 +757,3 @@ const structures = {
|
|
|
572
757
|
Rest: require("./Rest").Rest,
|
|
573
758
|
Utils: require("./Utils"),
|
|
574
759
|
};
|
|
575
|
-
var LoadTypes;
|
|
576
|
-
(function (LoadTypes) {
|
|
577
|
-
LoadTypes["Track"] = "track";
|
|
578
|
-
LoadTypes["Playlist"] = "playlist";
|
|
579
|
-
LoadTypes["Search"] = "search";
|
|
580
|
-
LoadTypes["Empty"] = "empty";
|
|
581
|
-
LoadTypes["Error"] = "error";
|
|
582
|
-
})(LoadTypes || (exports.LoadTypes = LoadTypes = {}));
|
|
583
|
-
var StateTypes;
|
|
584
|
-
(function (StateTypes) {
|
|
585
|
-
StateTypes["Connected"] = "CONNECTED";
|
|
586
|
-
StateTypes["Connecting"] = "CONNECTING";
|
|
587
|
-
StateTypes["Disconnected"] = "DISCONNECTED";
|
|
588
|
-
StateTypes["Disconnecting"] = "DISCONNECTING";
|
|
589
|
-
StateTypes["Destroying"] = "DESTROYING";
|
|
590
|
-
})(StateTypes || (exports.StateTypes = StateTypes = {}));
|
|
591
|
-
var TrackEndReasonTypes;
|
|
592
|
-
(function (TrackEndReasonTypes) {
|
|
593
|
-
TrackEndReasonTypes["Finished"] = "finished";
|
|
594
|
-
TrackEndReasonTypes["LoadFailed"] = "loadFailed";
|
|
595
|
-
TrackEndReasonTypes["Stopped"] = "stopped";
|
|
596
|
-
TrackEndReasonTypes["Replaced"] = "replaced";
|
|
597
|
-
TrackEndReasonTypes["Cleanup"] = "cleanup";
|
|
598
|
-
})(TrackEndReasonTypes || (exports.TrackEndReasonTypes = TrackEndReasonTypes = {}));
|
|
599
|
-
var SeverityTypes;
|
|
600
|
-
(function (SeverityTypes) {
|
|
601
|
-
SeverityTypes["Common"] = "common";
|
|
602
|
-
SeverityTypes["Suspicious"] = "suspicious";
|
|
603
|
-
SeverityTypes["Fault"] = "fault";
|
|
604
|
-
})(SeverityTypes || (exports.SeverityTypes = SeverityTypes = {}));
|
|
605
|
-
var TrackSourceTypes;
|
|
606
|
-
(function (TrackSourceTypes) {
|
|
607
|
-
TrackSourceTypes["AppleMusic"] = "applemusic";
|
|
608
|
-
TrackSourceTypes["Bandcamp"] = "bandcamp";
|
|
609
|
-
TrackSourceTypes["Deezer"] = "deezer";
|
|
610
|
-
TrackSourceTypes["Jiosaavn"] = "jiosaavn";
|
|
611
|
-
TrackSourceTypes["SoundCloud"] = "soundcloud";
|
|
612
|
-
TrackSourceTypes["Spotify"] = "spotify";
|
|
613
|
-
TrackSourceTypes["Tidal"] = "tidal";
|
|
614
|
-
TrackSourceTypes["VKMusic"] = "vkmusic";
|
|
615
|
-
TrackSourceTypes["YouTube"] = "youtube";
|
|
616
|
-
})(TrackSourceTypes || (exports.TrackSourceTypes = TrackSourceTypes = {}));
|