magmastream 2.9.0-dev.2 → 2.9.0-dev.3

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.
@@ -606,6 +606,8 @@ class Node {
606
606
  return false;
607
607
  const lastTrack = player.queue.previous[player.queue.previous.length - 1];
608
608
  lastTrack.requester = player.get("Internal_BotUser");
609
+ if (!lastTrack)
610
+ return false;
609
611
  const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(player, lastTrack, attempt);
610
612
  if (tracks.length) {
611
613
  player.queue.add(tracks[0]);
@@ -144,29 +144,22 @@ class AutoPlayUtils {
144
144
  this.manager = manager;
145
145
  }
146
146
  static async getRecommendedTracks(player, track, attempt = 0) {
147
- console.log(`[AutoPlay] Attempt ${attempt} for track: ${track.title}`);
148
147
  const node = this.manager.useableNode;
149
148
  if (!node) {
150
- console.error("[AutoPlay] No available nodes.");
151
149
  throw new Error("No available nodes.");
152
150
  }
153
151
  if (!player.isAutoplay) {
154
- console.log("[AutoPlay] Autoplay is disabled. Returning an empty array.");
155
152
  return [];
156
153
  }
157
154
  if (attempt >= player.autoplayTries) {
158
- console.warn(`[AutoPlay] Reached max autoplay attempts (${player.autoplayTries}).`);
159
155
  return [];
160
156
  }
161
157
  if (!player.queue.previous.length) {
162
- console.log("[AutoPlay] No previous tracks in the queue. Cannot generate recommendations.");
163
158
  return [];
164
159
  }
165
160
  const apiKey = this.manager.options.lastFmApiKey;
166
161
  const enabledSources = node.info.sourceManagers;
167
162
  const { autoPlaySearchPlatform } = this.manager.options;
168
- console.log(`[AutoPlay] Enabled sources: ${enabledSources.join(", ")}`);
169
- console.log(`[AutoPlay] Preferred autoplay platform: ${autoPlaySearchPlatform}`);
170
163
  const supportedPlatforms = ["spotify", "deezer", "soundcloud", "youtube"];
171
164
  const platformMapping = {
172
165
  [Manager_1.SearchPlatform.AppleMusic]: "applemusic",
@@ -183,125 +176,95 @@ class AutoPlayUtils {
183
176
  const mappedPlatform = platformMapping[autoPlaySearchPlatform];
184
177
  // Last attempt fallback to YouTube
185
178
  if (attempt === player.autoplayTries - 1 && player.autoplayTries > 1 && enabledSources.includes("youtube")) {
186
- console.log("[AutoPlay] Final attempt: Falling back to YouTube recommendations.");
187
179
  return await this.getRecommendedTracksFromYouTube(track);
188
180
  }
189
181
  // Check if the preferred autoplay platform is supported and enabled
190
182
  if (mappedPlatform && supportedPlatforms.includes(mappedPlatform) && enabledSources.includes(mappedPlatform)) {
191
- console.log(`[AutoPlay] Using recommended platform: ${mappedPlatform}`);
192
183
  return await this.getRecommendedTracksFromSource(track, mappedPlatform);
193
184
  }
194
185
  // Check if Last.fm API is available
195
186
  if (apiKey) {
196
- console.log("[AutoPlay] No preferred platform found. Using Last.fm recommendations.");
197
187
  return await this.getRecommendedTracksFromLastFm(track, apiKey);
198
188
  }
199
189
  // Fallback to YouTube if all else fails
200
190
  if (enabledSources.includes("youtube")) {
201
- console.warn("[AutoPlay] No other sources available. Falling back to YouTube.");
202
191
  return await this.getRecommendedTracksFromYouTube(track);
203
192
  }
204
- console.error("[AutoPlay] No suitable platform found. Returning an empty array.");
205
193
  return [];
206
194
  }
207
195
  static async getRecommendedTracksFromLastFm(track, apiKey) {
208
196
  const enabledSources = this.manager.useableNode.info.sourceManagers;
209
197
  const selectedSource = this.selectPlatform(enabledSources);
210
- console.log(`[AutoPlay] Selected source: ${selectedSource}`);
211
198
  let { author: artist } = track;
212
199
  const { title } = track;
213
- console.log(`[AutoPlay] Searching for recommended tracks for: ${artist} - ${title}`);
214
200
  if (!artist || !title) {
215
201
  if (!title) {
216
202
  // No title provided, search for the artist's top tracks
217
203
  const noTitleUrl = `https://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=${artist}&autocorrect=1&api_key=${apiKey}&format=json`;
218
- console.log(`[AutoPlay] No title provided. Fetching artist's top tracks from: ${noTitleUrl}`);
219
204
  const response = await axios_1.default.get(noTitleUrl);
220
205
  if (response.data.error || !response.data.toptracks?.track?.length) {
221
- console.error("[AutoPlay] Error or no tracks found for the artist. Returning an empty array.");
222
206
  return [];
223
207
  }
224
- console.log("[AutoPlay] Successfully fetched artist's top tracks.");
225
208
  const randomTrack = response.data.toptracks.track[Math.floor(Math.random() * response.data.toptracks.track.length)];
226
- console.log(`[AutoPlay] Selected random track: ${randomTrack.artist.name} - ${randomTrack.name}`);
227
209
  const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: selectedSource }, track.requester);
228
210
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
229
- console.error("[AutoPlay] Search returned empty or error result. Returning an empty array.");
230
211
  return [];
231
212
  }
232
213
  const filteredTracks = res.tracks.filter((t) => t.uri !== track.uri);
233
214
  if (!filteredTracks.length) {
234
- console.error("[AutoPlay] No suitable tracks found. Returning an empty array.");
235
215
  return [];
236
216
  }
237
- console.log("[AutoPlay] Found suitable tracks.");
238
217
  return filteredTracks;
239
218
  }
240
219
  if (!artist) {
241
220
  // No artist provided, search for the track title
242
221
  const noArtistUrl = `https://ws.audioscrobbler.com/2.0/?method=track.search&track=${title}&api_key=${apiKey}&format=json`;
243
- console.log(`[AutoPlay] No artist provided. Searching for track: ${title} from: ${noArtistUrl}`);
244
222
  const response = await axios_1.default.get(noArtistUrl);
245
223
  artist = response.data.results.trackmatches?.track?.[0]?.artist;
246
224
  if (!artist) {
247
- console.error("[AutoPlay] No artist found for track. Returning an empty array.");
248
225
  return [];
249
226
  }
250
- console.log(`[AutoPlay] Found artist for track: ${artist}`);
251
227
  }
252
228
  }
253
229
  // Search for similar tracks to the current track
254
230
  const url = `https://ws.audioscrobbler.com/2.0/?method=track.getSimilar&artist=${artist}&track=${title}&limit=10&autocorrect=1&api_key=${apiKey}&format=json`;
255
- console.log(`[AutoPlay] Searching for similar tracks using URL: ${url}`);
256
231
  let response;
257
232
  try {
258
233
  response = await axios_1.default.get(url);
259
- console.log("[AutoPlay] Successfully fetched similar tracks.");
260
234
  }
261
235
  catch (error) {
262
- console.error("[AutoPlay] Error fetching similar tracks. Returning an empty array.");
263
236
  console.log(error);
264
237
  return [];
265
238
  }
266
239
  if (response.data.error || !response.data.similartracks?.track?.length) {
267
- console.error("[AutoPlay] Error or no similar tracks found. Retrying with top tracks.");
268
240
  // Retry the request if the first attempt fails
269
241
  const retryUrl = `https://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=${artist}&autocorrect=1&api_key=${apiKey}&format=json`;
270
242
  const retryResponse = await axios_1.default.get(retryUrl);
271
243
  if (retryResponse.data.error || !retryResponse.data.toptracks?.track?.length) {
272
- console.error("[AutoPlay] Retry failed. Returning an empty array.");
273
244
  return [];
274
245
  }
275
246
  const randomTrack = retryResponse.data.toptracks.track[Math.floor(Math.random() * retryResponse.data.toptracks.track.length)];
276
- console.log(`[AutoPlay] Selected random track from retry: ${randomTrack.artist.name} - ${randomTrack.name}`);
277
247
  const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: selectedSource }, track.requester);
278
248
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
279
- console.error("[AutoPlay] Retry search returned empty or error result. Returning an empty array.");
280
249
  return [];
281
250
  }
282
251
  const filteredTracks = res.tracks.filter((t) => t.uri !== track.uri);
283
252
  if (!filteredTracks.length) {
284
- console.error("[AutoPlay] No suitable tracks found in retry. Returning an empty array.");
285
253
  return [];
286
254
  }
287
- console.log("[AutoPlay] Found suitable tracks from retry.");
288
255
  return filteredTracks;
289
256
  }
290
257
  const randomTrack = response.data.similartracks.track.sort(() => Math.random() - 0.5).shift();
291
258
  if (!randomTrack) {
292
- console.error("[AutoPlay] No similar tracks found after filtering. Returning an empty array.");
293
259
  return [];
294
260
  }
295
- console.log(`[AutoPlay] Selected random track: ${randomTrack.name} - ${randomTrack.artist.name}`);
296
261
  const res = await this.manager.search({ query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: selectedSource }, track.requester);
297
262
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
298
- console.error("[AutoPlay] Final search returned empty or error result. Returning an empty array.");
299
263
  return [];
300
264
  }
301
265
  if (res.loadType === LoadTypes.Playlist)
302
266
  res.tracks = res.playlist.tracks;
303
267
  if (!res.tracks.length) {
304
- console.error("[AutoPlay] No tracks found in final search. Returning an empty array.");
305
268
  return [];
306
269
  }
307
270
  return res.tracks;
@@ -309,108 +272,104 @@ class AutoPlayUtils {
309
272
  static async getRecommendedTracksFromSource(track, mappedPlatform) {
310
273
  switch (mappedPlatform) {
311
274
  case "spotify":
312
- console.log("[AutoPlay] Checking if track URI includes 'spotify':", track.uri);
313
- if (!track.uri.includes("spotify")) {
314
- console.log("[AutoPlay] Track URI does not include 'spotify'. Searching for track:", `${track.author} - ${track.title}`);
315
- const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.Spotify }, track.requester);
275
+ try {
276
+ if (!track.uri.includes("spotify")) {
277
+ const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.Spotify }, track.requester);
278
+ if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
279
+ return [];
280
+ }
281
+ if (res.loadType === LoadTypes.Playlist) {
282
+ res.tracks = res.playlist.tracks;
283
+ }
284
+ if (!res.tracks.length) {
285
+ return [];
286
+ }
287
+ track = res.tracks[0];
288
+ }
289
+ const TOTP_SECRET = new Uint8Array([
290
+ 53, 53, 48, 55, 49, 52, 53, 56, 53, 51, 52, 56, 55, 52, 57, 57, 53, 57, 50, 50, 52, 56, 54, 51, 48, 51, 50, 57, 51, 52, 55,
291
+ ]);
292
+ const hmac = crypto_1.default.createHmac("sha1", TOTP_SECRET);
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;
316
+ }
317
+ catch (error) {
318
+ console.error("[AutoPlay] Failed to get access token:", error.response?.status, error.response?.data || error.message);
319
+ return [];
320
+ }
321
+ let json;
322
+ try {
323
+ const response = await axios_1.default.get(`https://api.spotify.com/v1/recommendations`, {
324
+ params: { limit: 10, seed_tracks: track.identifier },
325
+ headers: {
326
+ Authorization: `Bearer ${body.accessToken}`,
327
+ "Content-Type": "application/json",
328
+ },
329
+ });
330
+ json = response.data;
331
+ }
332
+ catch (error) {
333
+ console.error("[AutoPlay] Failed to fetch recommendations:", error.response?.status, error.response?.data || error.message);
334
+ return [];
335
+ }
336
+ if (!json.tracks || !json.tracks.length) {
337
+ return [];
338
+ }
339
+ const recommendedTrackId = json.tracks[Math.floor(Math.random() * json.tracks.length)].id;
340
+ const res = await this.manager.search({ query: `https://open.spotify.com/track/${recommendedTrackId}`, source: Manager_1.SearchPlatform.Spotify }, track.requester);
316
341
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
317
- console.error("[AutoPlay] Search returned empty or error result. Returning an empty array.");
318
342
  return [];
319
343
  }
320
344
  if (res.loadType === LoadTypes.Playlist) {
321
- console.log("[AutoPlay] Search returned a playlist. Flattening tracks.");
322
345
  res.tracks = res.playlist.tracks;
323
346
  }
324
347
  if (!res.tracks.length) {
325
- console.error("[AutoPlay] No tracks found in the search. Returning an empty array.");
326
348
  return [];
327
349
  }
328
- console.log("[AutoPlay] Track found in search:", res.tracks[0].uri);
329
- track = res.tracks[0];
330
- }
331
- const TOTP_SECRET = new Uint8Array([
332
- 53, 53, 48, 55, 49, 52, 53, 56, 53, 51, 52, 56, 55, 52, 57, 57, 53, 57, 50, 50, 52, 56, 54, 51, 48, 51, 50, 57, 51, 52, 55,
333
- ]);
334
- const hmac = crypto_1.default.createHmac("sha1", TOTP_SECRET);
335
- function generateTotp() {
336
- const counter = Math.floor(Date.now() / 30000);
337
- const counterBuffer = Buffer.alloc(8);
338
- counterBuffer.writeBigInt64BE(BigInt(counter));
339
- hmac.update(counterBuffer);
340
- const hmacResult = hmac.digest();
341
- const offset = hmacResult[hmacResult.length - 1] & 15;
342
- const truncatedValue = ((hmacResult[offset] & 127) << 24) | ((hmacResult[offset + 1] & 255) << 16) | ((hmacResult[offset + 2] & 255) << 8) | (hmacResult[offset + 3] & 255);
343
- const totp = (truncatedValue % 1000000).toString().padStart(6, "0");
344
- return [totp, counter * 30000];
345
- }
346
- const [totp, timestamp] = generateTotp();
347
- console.log("[AutoPlay] Generated TOTP:", totp);
348
- const params = {
349
- reason: "transport",
350
- productType: "embed",
351
- totp: totp,
352
- totpVer: 5,
353
- ts: timestamp,
354
- };
355
- console.log("[AutoPlay] Sending request to get access token with params:", params);
356
- const { data: body } = await axios_1.default.get("https://open.spotify.com/get_access_token", { params });
357
- console.log("[AutoPlay] Access token received.");
358
- const { data: json } = await axios_1.default.get(`https://api.spotify.com/v1/recommendations`, {
359
- params: { limit: 10, seed_tracks: track.identifier },
360
- headers: {
361
- Authorization: `Bearer ${body.accessToken}`,
362
- "Content-Type": "application/json",
363
- },
364
- });
365
- if (!json.tracks || !json.tracks.length) {
366
- console.error("[AutoPlay] No recommended tracks received from Spotify API. Returning an empty array.");
367
- return [];
368
- }
369
- console.log("[AutoPlay] Recommended tracks received from Spotify.");
370
- // Return a random recommended track ID
371
- const recommendedTrackId = json.tracks[Math.floor(Math.random() * json.tracks.length)].id;
372
- console.log(`[AutoPlay] Selected random recommended track ID: ${recommendedTrackId}`);
373
- console.log("[AutoPlay] Searching for the recommended track:", recommendedTrackId);
374
- const res = await this.manager.search({ query: `https://open.spotify.com/track/${recommendedTrackId}`, source: Manager_1.SearchPlatform.Spotify }, track.requester);
375
- if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
376
- console.error("[AutoPlay] Final search returned empty or error result. Returning an empty array.");
377
- return [];
378
- }
379
- if (res.loadType === LoadTypes.Playlist) {
380
- console.log("[AutoPlay] Final search returned a playlist. Flattening tracks.");
381
- res.tracks = res.playlist.tracks;
350
+ return res.tracks;
382
351
  }
383
- if (!res.tracks.length) {
384
- console.error("[AutoPlay] No tracks found in final search. Returning an empty array.");
352
+ catch (error) {
353
+ console.error("[AutoPlay] Unexpected error:", error.message || error);
385
354
  return [];
386
355
  }
387
- console.log("[AutoPlay] Recommended tracks found and ready to return.");
388
- return res.tracks;
389
356
  case "deezer":
390
- console.log("[AutoPlay] Checking if track URI includes 'deezer':", track.uri);
391
357
  if (!track.uri.includes("deezer")) {
392
- console.log("[AutoPlay] Track URI does not include 'deezer'. Searching for track:", `${track.author} - ${track.title}`);
393
358
  const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.Deezer }, track.requester);
394
359
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
395
- console.error("[AutoPlay] Search returned empty or error result. Returning an empty array.");
396
360
  return [];
397
361
  }
398
362
  if (res.loadType === LoadTypes.Playlist) {
399
- console.log("[AutoPlay] Search returned a playlist. Flattening tracks.");
400
363
  res.tracks = res.playlist.tracks;
401
364
  }
402
365
  if (!res.tracks.length) {
403
- console.error("[AutoPlay] No tracks found in the search. Returning an empty array.");
404
366
  return [];
405
367
  }
406
- console.log("[AutoPlay] Track found in search:", res.tracks[0].uri);
407
368
  track = res.tracks[0];
408
369
  }
409
370
  const identifier = `dzrec:${track.identifier}`;
410
- console.log("[AutoPlay] Generating Deezer recommendation identifier:", identifier);
411
371
  const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
412
372
  if (!recommendedResult) {
413
- console.error("[AutoPlay] No recommended result received from Deezer. Returning an empty array.");
414
373
  return [];
415
374
  }
416
375
  let tracks = [];
@@ -418,15 +377,12 @@ class AutoPlayUtils {
418
377
  const requester = track.requester;
419
378
  switch (recommendedResult.loadType) {
420
379
  case LoadTypes.Search:
421
- console.log("[AutoPlay] Recommended result is of type 'Search'. Building tracks.");
422
380
  tracks = recommendedResult.data.map((track) => TrackUtils.build(track, requester));
423
381
  break;
424
382
  case LoadTypes.Track:
425
- console.log("[AutoPlay] Recommended result is of type 'Track'. Building a single track.");
426
383
  tracks = [TrackUtils.build(recommendedResult.data, requester)];
427
384
  break;
428
385
  case LoadTypes.Playlist: {
429
- console.log("[AutoPlay] Recommended result is of type 'Playlist'. Building playlist.");
430
386
  const playlistData = recommendedResult.data;
431
387
  tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
432
388
  playlist = {
@@ -441,42 +397,37 @@ class AutoPlayUtils {
441
397
  }
442
398
  const result = { loadType: recommendedResult.loadType, tracks, playlist };
443
399
  if (result.loadType === LoadTypes.Empty || result.loadType === LoadTypes.Error) {
444
- console.error("[AutoPlay] Final result load type is empty or error. Returning an empty array.");
445
400
  return [];
446
401
  }
447
402
  if (result.loadType === LoadTypes.Playlist) {
448
- console.log("[AutoPlay] Final result load type is Playlist. Flattening tracks.");
449
403
  result.tracks = result.playlist.tracks;
450
404
  }
451
405
  if (!result.tracks.length) {
452
- console.error("[AutoPlay] No tracks found in final result. Returning an empty array.");
453
406
  return [];
454
407
  }
455
- console.log("[AutoPlay] Tracks found and ready to return.");
456
408
  return result.tracks;
457
409
  case "soundcloud":
458
- console.log("[AutoPlay] Checking if track URI includes 'soundcloud':", track.uri);
459
410
  if (!track.uri.includes("soundcloud")) {
460
- console.log("[AutoPlay] Track URI does not include 'soundcloud'. Searching for track:", `${track.author} - ${track.title}`);
461
411
  const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.SoundCloud }, track.requester);
462
412
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
463
- console.error("[AutoPlay] Search returned empty or error result. Returning an empty array.");
464
413
  return [];
465
414
  }
466
415
  if (res.loadType === LoadTypes.Playlist) {
467
- console.log("[AutoPlay] Search returned a playlist. Flattening tracks.");
468
416
  res.tracks = res.playlist.tracks;
469
417
  }
470
418
  if (!res.tracks.length) {
471
- console.error("[AutoPlay] No tracks found in the search. Returning an empty array.");
472
419
  return [];
473
420
  }
474
- console.log("[AutoPlay] Track found in search:", res.tracks[0].uri);
475
421
  track = res.tracks[0];
476
422
  }
477
423
  try {
478
- console.log("[AutoPlay] Fetching SoundCloud recommendations from:", `${track.uri}/recommended`);
479
- const recommendedRes = await axios_1.default.get(`${track.uri}/recommended`);
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 [];
430
+ }
480
431
  const html = recommendedRes.data;
481
432
  const dom = new jsdom_1.JSDOM(html);
482
433
  const document = dom.window.document;
@@ -484,7 +435,6 @@ class AutoPlayUtils {
484
435
  const sectionElement = secondNoscript.querySelector("section");
485
436
  const articleElements = sectionElement.querySelectorAll("article");
486
437
  if (!articleElements || articleElements.length === 0) {
487
- console.error("[AutoPlay] No article elements found for recommendations. Returning an empty array.");
488
438
  return [];
489
439
  }
490
440
  const urls = Array.from(articleElements)
@@ -495,77 +445,55 @@ class AutoPlayUtils {
495
445
  })
496
446
  .filter(Boolean);
497
447
  if (!urls.length) {
498
- console.error("[AutoPlay] No valid URLs found in the recommendations. Returning an empty array.");
499
448
  return [];
500
449
  }
501
450
  const randomUrl = urls[Math.floor(Math.random() * urls.length)];
502
- console.log("[AutoPlay] Selected random URL for recommended track:", randomUrl);
503
451
  const res = await this.manager.search({ query: randomUrl, source: Manager_1.SearchPlatform.SoundCloud }, track.requester);
504
452
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
505
- console.error("[AutoPlay] Search for recommended track returned empty or error result. Returning an empty array.");
506
453
  return [];
507
454
  }
508
455
  if (res.loadType === LoadTypes.Playlist) {
509
- console.log("[AutoPlay] Search for recommended track returned a playlist. Flattening tracks.");
510
456
  res.tracks = res.playlist.tracks;
511
457
  }
512
458
  if (!res.tracks.length) {
513
- console.error("[AutoPlay] No tracks found in the search for recommended track. Returning an empty array.");
514
459
  return [];
515
460
  }
516
- console.log("[AutoPlay] Found recommended tracks:", res.tracks.map((track) => track.uri));
517
461
  return res.tracks;
518
462
  }
519
463
  catch (error) {
520
464
  console.error("[AutoPlay] Error occurred while fetching recommendations:", error);
521
465
  return [];
522
466
  }
523
- break;
524
467
  case "youtube":
525
468
  return this.getRecommendedTracksFromYouTube(track);
526
- break;
527
469
  default:
528
470
  return [];
529
471
  }
530
472
  }
531
473
  static async getRecommendedTracksFromYouTube(track) {
532
- console.log("[YouTube Recommendation] Checking if track URI includes YouTube URL:", track.uri);
533
- // Check if the previous track has a YouTube URL
534
474
  const hasYouTubeURL = ["youtube.com", "youtu.be"].some((url) => track.uri.includes(url));
535
475
  let videoID = null;
536
476
  if (hasYouTubeURL) {
537
- console.log("[YouTube Recommendation] Track contains a YouTube URL. Extracting video ID from URI.");
538
477
  videoID = track.uri.split("=").pop();
539
478
  }
540
479
  else {
541
- console.log("[YouTube Recommendation] Track does not contain a YouTube URL. Searching for the track on YouTube.");
542
480
  const searchResult = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.YouTube }, track.requester);
543
481
  videoID = searchResult.tracks[0]?.uri.split("=").pop();
544
482
  }
545
483
  if (!videoID) {
546
- console.error("[YouTube Recommendation] Video ID not found. Returning an empty array.");
547
484
  return [];
548
485
  }
549
- console.log("[YouTube Recommendation] Video ID extracted:", videoID);
550
- // Get a random video index between 2 and 24
551
486
  let randomIndex;
552
487
  let searchURI;
553
488
  do {
554
- randomIndex = Math.floor(Math.random() * 23) + 2; // Random index between 2 and 24
489
+ randomIndex = Math.floor(Math.random() * 23) + 2;
555
490
  searchURI = `https://www.youtube.com/watch?v=${videoID}&list=RD${videoID}&index=${randomIndex}`;
556
- console.log("[YouTube Recommendation] Generated random search URI:", searchURI);
557
491
  } while (track.uri.includes(searchURI));
558
- // Search for the video and return false if the search fails
559
- console.log("[YouTube Recommendation] Searching for the video using search URI:", searchURI);
560
492
  const res = await this.manager.search({ query: searchURI, source: Manager_1.SearchPlatform.YouTube }, track.requester);
561
493
  if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
562
- console.error("[YouTube Recommendation] Search failed or returned empty results. Returning an empty array.");
563
494
  return [];
564
495
  }
565
- // Filter out tracks that have the same URI as the current track
566
- console.log("[YouTube Recommendation] Filtering tracks that do not match the current track URI.");
567
496
  const filteredTracks = res.tracks.filter((t) => t.uri !== track.uri);
568
- console.log("[YouTube Recommendation] Returning filtered recommended tracks:", filteredTracks.map((t) => t.uri));
569
497
  return filteredTracks;
570
498
  }
571
499
  static selectPlatform(enabledSources) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.0-dev.2",
3
+ "version": "2.9.0-dev.3",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",