discord-player 5.2.3-dev → 5.3.0-dev.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/dist/Player.js CHANGED
@@ -26,7 +26,6 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
26
26
  * @param {PlayerInitOptions} [options={}] The player init options
27
27
  */
28
28
  constructor(client, options = {}) {
29
- var _a, _b, _c, _d, _e;
30
29
  super();
31
30
  this.options = {
32
31
  autoRegisterExtractor: true,
@@ -44,8 +43,8 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
44
43
  * @type {Client}
45
44
  */
46
45
  this.client = client;
47
- if (((_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.intents) && !new discord_js_1.Intents((_d = (_c = this.client) === null || _c === void 0 ? void 0 : _c.options) === null || _d === void 0 ? void 0 : _d.intents).has(discord_js_1.Intents.FLAGS.GUILD_VOICE_STATES)) {
48
- throw new PlayerError_1.PlayerError('client is missing "GUILD_VOICE_STATES" intent');
46
+ if (this.client?.options?.intents && !new discord_js_1.IntentsBitField(this.client?.options?.intents).has(discord_js_1.IntentsBitField.Flags.GuildVoiceStates)) {
47
+ throw new PlayerError_1.PlayerError('client is missing "GuildVoiceStates" intent');
49
48
  }
50
49
  /**
51
50
  * The extractors collection
@@ -53,7 +52,7 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
53
52
  */
54
53
  this.options = Object.assign(this.options, options);
55
54
  this.client.on("voiceStateUpdate", this._handleVoiceState.bind(this));
56
- if ((_e = this.options) === null || _e === void 0 ? void 0 : _e.autoRegisterExtractor) {
55
+ if (this.options?.autoRegisterExtractor) {
57
56
  let nv; // eslint-disable-line @typescript-eslint/no-explicit-any
58
57
  if ((nv = Util_1.Util.require("@discord-player/extractor"))) {
59
58
  ["Attachment", "Facebook", "Reverbnation", "Vimeo"].forEach((ext) => void this.use(ext, nv[ext]));
@@ -69,34 +68,34 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
69
68
  */
70
69
  _handleVoiceState(oldState, newState) {
71
70
  const queue = this.getQueue(oldState.guild.id);
72
- if (!queue)
71
+ if (!queue || !queue.connection)
73
72
  return;
74
- if (oldState.channelId && !newState.channelId && newState.member.id === newState.guild.me.id) {
73
+ if (oldState.channelId && !newState.channelId && newState.member.id === newState.guild.members.me.id) {
75
74
  try {
76
75
  queue.destroy();
77
76
  }
78
- catch (_a) {
77
+ catch {
79
78
  /* noop */
80
79
  }
81
80
  return void this.emit("botDisconnect", queue);
82
81
  }
83
- if (!oldState.channelId && newState.channelId && newState.member.id === newState.guild.me.id) {
82
+ if (!oldState.channelId && newState.channelId && newState.member.id === newState.guild.members.me.id) {
84
83
  if (newState.serverMute || !newState.serverMute) {
85
84
  queue.setPaused(newState.serverMute);
86
85
  }
87
86
  else if (newState.suppress || !newState.suppress) {
88
87
  if (newState.suppress)
89
- newState.guild.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
88
+ newState.guild.members.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
90
89
  queue.setPaused(newState.suppress);
91
90
  }
92
91
  }
93
- if (oldState.channelId === newState.channelId && newState.member.id === newState.guild.me.id) {
92
+ if (oldState.channelId === newState.channelId && newState.member.id === newState.guild.members.me.id) {
94
93
  if (oldState.serverMute !== newState.serverMute) {
95
94
  queue.setPaused(newState.serverMute);
96
95
  }
97
96
  else if (oldState.suppress !== newState.suppress) {
98
97
  if (newState.suppress)
99
- newState.guild.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
98
+ newState.guild.members.me.voice.setRequestToSpeak(true).catch(Util_1.Util.noop);
100
99
  queue.setPaused(newState.suppress);
101
100
  }
102
101
  }
@@ -109,7 +108,7 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
109
108
  if (!this.queues.has(queue.guild.id))
110
109
  return;
111
110
  if (queue.options.leaveOnEmpty)
112
- queue.destroy();
111
+ queue.destroy(true);
113
112
  this.emit("channelEmpty", queue);
114
113
  }, queue.options.leaveOnEmptyCooldown || 0).unref();
115
114
  queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
@@ -122,8 +121,8 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
122
121
  queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
123
122
  }
124
123
  }
125
- if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId && newState.member.id === newState.guild.me.id) {
126
- if (queue.connection && newState.member.id === newState.guild.me.id)
124
+ if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId && newState.member.id === newState.guild.members.me.id) {
125
+ if (queue.connection && newState.member.id === newState.guild.members.me.id)
127
126
  queue.connection.channel = newState.channel;
128
127
  const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
129
128
  const channelEmpty = Util_1.Util.isVoiceEmpty(queue.connection.channel);
@@ -138,7 +137,7 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
138
137
  if (!this.queues.has(queue.guild.id))
139
138
  return;
140
139
  if (queue.options.leaveOnEmpty)
141
- queue.destroy();
140
+ queue.destroy(true);
142
141
  this.emit("channelEmpty", queue);
143
142
  }, queue.options.leaveOnEmptyCooldown || 0).unref();
144
143
  queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
@@ -152,7 +151,6 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
152
151
  * @returns {Queue}
153
152
  */
154
153
  createQueue(guild, queueInitOptions = {}) {
155
- var _a, _b;
156
154
  guild = this.client.guilds.resolve(guild);
157
155
  if (!guild)
158
156
  throw new PlayerError_1.PlayerError("Unknown Guild", PlayerError_1.ErrorStatusCode.UNKNOWN_GUILD);
@@ -160,8 +158,8 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
160
158
  return this.queues.get(guild.id);
161
159
  const _meta = queueInitOptions.metadata;
162
160
  delete queueInitOptions["metadata"];
163
- (_a = queueInitOptions.volumeSmoothness) !== null && _a !== void 0 ? _a : (queueInitOptions.volumeSmoothness = 0.08);
164
- (_b = queueInitOptions.ytdlOptions) !== null && _b !== void 0 ? _b : (queueInitOptions.ytdlOptions = this.options.ytdlOptions);
161
+ queueInitOptions.volumeSmoothness ?? (queueInitOptions.volumeSmoothness = 0.08);
162
+ queueInitOptions.ytdlOptions ?? (queueInitOptions.ytdlOptions = this.options.ytdlOptions);
165
163
  const queue = new Queue_1.Queue(this, guild, queueInitOptions);
166
164
  queue.metadata = _meta;
167
165
  this.queues.set(guild.id, queue);
@@ -191,7 +189,7 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
191
189
  try {
192
190
  prev.destroy();
193
191
  }
194
- catch (_a) { } // eslint-disable-line no-empty
192
+ catch { } // eslint-disable-line no-empty
195
193
  this.queues.delete(guild.id);
196
194
  return prev;
197
195
  }
@@ -206,281 +204,292 @@ class Player extends tiny_typed_emitter_1.TypedEmitter {
206
204
  * @param {SearchOptions} options The search options
207
205
  * @returns {Promise<PlayerSearchResult>}
208
206
  */
209
- search(query, options) {
210
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18;
211
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
212
- if (query instanceof Track_1.default)
213
- return { playlist: query.playlist || null, tracks: [query] };
214
- if (!options)
215
- throw new PlayerError_1.PlayerError("DiscordPlayer#search needs search options!", PlayerError_1.ErrorStatusCode.INVALID_ARG_TYPE);
216
- options.requestedBy = this.client.users.resolve(options.requestedBy);
217
- if (!("searchEngine" in options))
218
- options.searchEngine = types_1.QueryType.AUTO;
219
- if (typeof options.searchEngine === "string" && this.extractors.has(options.searchEngine)) {
220
- const extractor = this.extractors.get(options.searchEngine);
221
- if (!extractor.validate(query))
207
+ async search(query, options) {
208
+ if (query instanceof Track_1.default)
209
+ return { playlist: query.playlist || null, tracks: [query] };
210
+ if (!options)
211
+ throw new PlayerError_1.PlayerError("DiscordPlayer#search needs search options!", PlayerError_1.ErrorStatusCode.INVALID_ARG_TYPE);
212
+ options.requestedBy = this.client.users.resolve(options.requestedBy);
213
+ if (!("searchEngine" in options))
214
+ options.searchEngine = types_1.QueryType.AUTO;
215
+ if (typeof options.searchEngine === "string" && this.extractors.has(options.searchEngine)) {
216
+ const extractor = this.extractors.get(options.searchEngine);
217
+ if (!extractor.validate(query))
218
+ return { playlist: null, tracks: [] };
219
+ const data = await extractor.handle(query);
220
+ if (data && data.data.length) {
221
+ const playlist = !data.playlist
222
+ ? null
223
+ : new Playlist_1.Playlist(this, {
224
+ ...data.playlist,
225
+ tracks: []
226
+ });
227
+ const tracks = data.data.map((m) => new Track_1.default(this, {
228
+ ...m,
229
+ requestedBy: options.requestedBy,
230
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration)),
231
+ playlist: playlist
232
+ }));
233
+ if (playlist)
234
+ playlist.tracks = tracks;
235
+ return { playlist: playlist, tracks: tracks };
236
+ }
237
+ }
238
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
239
+ for (const [_, extractor] of this.extractors) {
240
+ if (options.blockExtractor)
241
+ break;
242
+ if (!extractor.validate(query))
243
+ continue;
244
+ const data = await extractor.handle(query);
245
+ if (data && data.data.length) {
246
+ const playlist = !data.playlist
247
+ ? null
248
+ : new Playlist_1.Playlist(this, {
249
+ ...data.playlist,
250
+ tracks: []
251
+ });
252
+ const tracks = data.data.map((m) => new Track_1.default(this, {
253
+ ...m,
254
+ requestedBy: options.requestedBy,
255
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration)),
256
+ playlist: playlist
257
+ }));
258
+ if (playlist)
259
+ playlist.tracks = tracks;
260
+ return { playlist: playlist, tracks: tracks };
261
+ }
262
+ }
263
+ const qt = options.searchEngine === types_1.QueryType.AUTO ? QueryResolver_1.QueryResolver.resolve(query) : options.searchEngine;
264
+ switch (qt) {
265
+ case types_1.QueryType.YOUTUBE_VIDEO: {
266
+ const info = await (0, ytdl_core_1.getInfo)(query, this.options.ytdlOptions).catch(Util_1.Util.noop);
267
+ if (!info)
222
268
  return { playlist: null, tracks: [] };
223
- const data = yield extractor.handle(query);
224
- if (data && data.data.length) {
225
- const playlist = !data.playlist
226
- ? null
227
- : new Playlist_1.Playlist(this, Object.assign(Object.assign({}, data.playlist), { tracks: [] }));
228
- const tracks = data.data.map((m) => new Track_1.default(this, Object.assign(Object.assign({}, m), { requestedBy: options.requestedBy, duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration)), playlist: playlist })));
229
- if (playlist)
230
- playlist.tracks = tracks;
231
- return { playlist: playlist, tracks: tracks };
232
- }
269
+ const track = new Track_1.default(this, {
270
+ title: info.videoDetails.title,
271
+ description: info.videoDetails.description,
272
+ author: info.videoDetails.author?.name,
273
+ url: info.videoDetails.video_url,
274
+ requestedBy: options.requestedBy,
275
+ thumbnail: Util_1.Util.last(info.videoDetails.thumbnails)?.url,
276
+ views: parseInt(info.videoDetails.viewCount.replace(/[^0-9]/g, "")) || 0,
277
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)),
278
+ source: "youtube",
279
+ raw: info
280
+ });
281
+ return { playlist: null, tracks: [track] };
233
282
  }
234
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
235
- for (const [_, extractor] of this.extractors) {
236
- if (options.blockExtractor)
237
- break;
238
- if (!extractor.validate(query))
239
- continue;
240
- const data = yield extractor.handle(query);
241
- if (data && data.data.length) {
242
- const playlist = !data.playlist
243
- ? null
244
- : new Playlist_1.Playlist(this, Object.assign(Object.assign({}, data.playlist), { tracks: [] }));
245
- const tracks = data.data.map((m) => new Track_1.default(this, Object.assign(Object.assign({}, m), { requestedBy: options.requestedBy, duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration)), playlist: playlist })));
246
- if (playlist)
247
- playlist.tracks = tracks;
248
- return { playlist: playlist, tracks: tracks };
249
- }
283
+ case types_1.QueryType.YOUTUBE_SEARCH: {
284
+ const videos = await youtube_sr_1.default.search(query, {
285
+ type: "video"
286
+ }).catch(Util_1.Util.noop);
287
+ if (!videos)
288
+ return { playlist: null, tracks: [] };
289
+ const tracks = videos.map((m) => {
290
+ m.source = "youtube"; // eslint-disable-line @typescript-eslint/no-explicit-any
291
+ return new Track_1.default(this, {
292
+ title: m.title,
293
+ description: m.description,
294
+ author: m.channel?.name,
295
+ url: m.url,
296
+ requestedBy: options.requestedBy,
297
+ thumbnail: m.thumbnail?.displayThumbnailURL("maxresdefault"),
298
+ views: m.views,
299
+ duration: m.durationFormatted,
300
+ source: "youtube",
301
+ raw: m
302
+ });
303
+ });
304
+ return { playlist: null, tracks };
250
305
  }
251
- const qt = options.searchEngine === types_1.QueryType.AUTO ? QueryResolver_1.QueryResolver.resolve(query) : options.searchEngine;
252
- switch (qt) {
253
- case types_1.QueryType.YOUTUBE_VIDEO: {
254
- const info = yield (0, ytdl_core_1.getInfo)(query, this.options.ytdlOptions).catch(Util_1.Util.noop);
255
- if (!info)
256
- return { playlist: null, tracks: [] };
306
+ case types_1.QueryType.SOUNDCLOUD_TRACK:
307
+ case types_1.QueryType.SOUNDCLOUD_SEARCH: {
308
+ const result = QueryResolver_1.QueryResolver.resolve(query) === types_1.QueryType.SOUNDCLOUD_TRACK ? [{ url: query }] : await soundcloud.search(query, "track").catch(() => []);
309
+ if (!result || !result.length)
310
+ return { playlist: null, tracks: [] };
311
+ const res = [];
312
+ for (const r of result) {
313
+ const trackInfo = await soundcloud.getSongInfo(r.url).catch(Util_1.Util.noop);
314
+ if (!trackInfo)
315
+ continue;
257
316
  const track = new Track_1.default(this, {
258
- title: info.videoDetails.title,
259
- description: info.videoDetails.description,
260
- author: (_a = info.videoDetails.author) === null || _a === void 0 ? void 0 : _a.name,
261
- url: info.videoDetails.video_url,
317
+ title: trackInfo.title,
318
+ url: trackInfo.url,
319
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(trackInfo.duration)),
320
+ description: trackInfo.description,
321
+ thumbnail: trackInfo.thumbnail,
322
+ views: trackInfo.playCount,
323
+ author: trackInfo.author.name,
262
324
  requestedBy: options.requestedBy,
263
- thumbnail: (_b = Util_1.Util.last(info.videoDetails.thumbnails)) === null || _b === void 0 ? void 0 : _b.url,
264
- views: parseInt(info.videoDetails.viewCount.replace(/[^0-9]/g, "")) || 0,
265
- duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)),
266
- source: "youtube",
267
- raw: info
325
+ source: "soundcloud",
326
+ engine: trackInfo
268
327
  });
269
- return { playlist: null, tracks: [track] };
328
+ res.push(track);
270
329
  }
271
- case types_1.QueryType.YOUTUBE_SEARCH: {
272
- const videos = yield youtube_sr_1.default.search(query, {
273
- type: "video"
274
- }).catch(Util_1.Util.noop);
275
- if (!videos)
276
- return { playlist: null, tracks: [] };
277
- const tracks = videos.map((m) => {
278
- var _a, _b;
279
- m.source = "youtube"; // eslint-disable-line @typescript-eslint/no-explicit-any
280
- return new Track_1.default(this, {
281
- title: m.title,
282
- description: m.description,
283
- author: (_a = m.channel) === null || _a === void 0 ? void 0 : _a.name,
284
- url: m.url,
330
+ return { playlist: null, tracks: res };
331
+ }
332
+ case types_1.QueryType.SPOTIFY_SONG: {
333
+ const spotifyData = await (0, spotify_url_info_1.default)(await Util_1.Util.getFetch())
334
+ .getData(query)
335
+ .catch(Util_1.Util.noop);
336
+ if (!spotifyData)
337
+ return { playlist: null, tracks: [] };
338
+ const spotifyTrack = new Track_1.default(this, {
339
+ title: spotifyData.name,
340
+ description: spotifyData.description ?? "",
341
+ author: spotifyData.artists[0]?.name ?? "Unknown Artist",
342
+ url: spotifyData.external_urls?.spotify ?? query,
343
+ thumbnail: spotifyData.album?.images[0]?.url ?? spotifyData.preview_url?.length
344
+ ? `https://i.scdn.co/image/${spotifyData.preview_url?.split("?cid=")[1]}`
345
+ : "https://www.scdn.co/i/_global/twitter_card-default.jpg",
346
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(spotifyData.duration_ms)),
347
+ views: 0,
348
+ requestedBy: options.requestedBy,
349
+ source: "spotify"
350
+ });
351
+ return { playlist: null, tracks: [spotifyTrack] };
352
+ }
353
+ case types_1.QueryType.SPOTIFY_PLAYLIST:
354
+ case types_1.QueryType.SPOTIFY_ALBUM: {
355
+ const spotifyPlaylist = await (0, spotify_url_info_1.default)(await Util_1.Util.getFetch())
356
+ .getData(query)
357
+ .catch(Util_1.Util.noop);
358
+ if (!spotifyPlaylist)
359
+ return { playlist: null, tracks: [] };
360
+ const playlist = new Playlist_1.Playlist(this, {
361
+ title: spotifyPlaylist.name ?? spotifyPlaylist.title,
362
+ description: spotifyPlaylist.description ?? "",
363
+ thumbnail: spotifyPlaylist.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg",
364
+ type: spotifyPlaylist.type,
365
+ source: "spotify",
366
+ author: spotifyPlaylist.type !== "playlist"
367
+ ? {
368
+ name: spotifyPlaylist.artists[0]?.name ?? "Unknown Artist",
369
+ url: spotifyPlaylist.artists[0]?.external_urls?.spotify ?? null
370
+ }
371
+ : {
372
+ name: spotifyPlaylist.owner?.display_name ?? spotifyPlaylist.owner?.id ?? "Unknown Artist",
373
+ url: spotifyPlaylist.owner?.external_urls?.spotify ?? null
374
+ },
375
+ tracks: [],
376
+ id: spotifyPlaylist.id,
377
+ url: spotifyPlaylist.external_urls?.spotify ?? query,
378
+ rawPlaylist: spotifyPlaylist
379
+ });
380
+ if (spotifyPlaylist.type !== "playlist") {
381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
+ playlist.tracks = spotifyPlaylist.tracks.items.map((m) => {
383
+ const data = new Track_1.default(this, {
384
+ title: m.name ?? "",
385
+ description: m.description ?? "",
386
+ author: m.artists[0]?.name ?? "Unknown Artist",
387
+ url: m.external_urls?.spotify ?? query,
388
+ thumbnail: spotifyPlaylist.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg",
389
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration_ms)),
390
+ views: 0,
285
391
  requestedBy: options.requestedBy,
286
- thumbnail: (_b = m.thumbnail) === null || _b === void 0 ? void 0 : _b.displayThumbnailURL("maxresdefault"),
287
- views: m.views,
288
- duration: m.durationFormatted,
289
- source: "youtube",
290
- raw: m
392
+ playlist,
393
+ source: "spotify"
291
394
  });
395
+ return data;
292
396
  });
293
- return { playlist: null, tracks };
294
397
  }
295
- case types_1.QueryType.SOUNDCLOUD_TRACK:
296
- case types_1.QueryType.SOUNDCLOUD_SEARCH: {
297
- const result = QueryResolver_1.QueryResolver.resolve(query) === types_1.QueryType.SOUNDCLOUD_TRACK ? [{ url: query }] : yield soundcloud.search(query, "track").catch(() => []);
298
- if (!result || !result.length)
299
- return { playlist: null, tracks: [] };
300
- const res = [];
301
- for (const r of result) {
302
- const trackInfo = yield soundcloud.getSongInfo(r.url).catch(Util_1.Util.noop);
303
- if (!trackInfo)
304
- continue;
305
- const track = new Track_1.default(this, {
306
- title: trackInfo.title,
307
- url: trackInfo.url,
308
- duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(trackInfo.duration)),
309
- description: trackInfo.description,
310
- thumbnail: trackInfo.thumbnail,
311
- views: trackInfo.playCount,
312
- author: trackInfo.author.name,
398
+ else {
399
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
400
+ playlist.tracks = spotifyPlaylist.tracks.items.map((m) => {
401
+ const data = new Track_1.default(this, {
402
+ title: m.track.name ?? "",
403
+ description: m.track.description ?? "",
404
+ author: m.track.artists[0]?.name ?? "Unknown Artist",
405
+ url: m.track.external_urls?.spotify ?? query,
406
+ thumbnail: m.track.album?.images[0]?.url ?? "https://www.scdn.co/i/_global/twitter_card-default.jpg",
407
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.track.duration_ms)),
408
+ views: 0,
313
409
  requestedBy: options.requestedBy,
314
- source: "soundcloud",
315
- engine: trackInfo
410
+ playlist,
411
+ source: "spotify"
316
412
  });
317
- res.push(track);
318
- }
319
- return { playlist: null, tracks: res };
320
- }
321
- case types_1.QueryType.SPOTIFY_SONG: {
322
- const spotifyData = yield spotify_url_info_1.default.getData(query).catch(Util_1.Util.noop);
323
- if (!spotifyData)
324
- return { playlist: null, tracks: [] };
325
- const spotifyTrack = new Track_1.default(this, {
326
- title: spotifyData.name,
327
- description: (_c = spotifyData.description) !== null && _c !== void 0 ? _c : "",
328
- author: (_e = (_d = spotifyData.artists[0]) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : "Unknown Artist",
329
- url: (_g = (_f = spotifyData.external_urls) === null || _f === void 0 ? void 0 : _f.spotify) !== null && _g !== void 0 ? _g : query,
330
- thumbnail: ((_k = (_j = (_h = spotifyData.album) === null || _h === void 0 ? void 0 : _h.images[0]) === null || _j === void 0 ? void 0 : _j.url) !== null && _k !== void 0 ? _k : (_l = spotifyData.preview_url) === null || _l === void 0 ? void 0 : _l.length)
331
- ? `https://i.scdn.co/image/${(_m = spotifyData.preview_url) === null || _m === void 0 ? void 0 : _m.split("?cid=")[1]}`
332
- : "https://www.scdn.co/i/_global/twitter_card-default.jpg",
333
- duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(spotifyData.duration_ms)),
334
- views: 0,
335
- requestedBy: options.requestedBy,
336
- source: "spotify"
337
- });
338
- return { playlist: null, tracks: [spotifyTrack] };
339
- }
340
- case types_1.QueryType.SPOTIFY_PLAYLIST:
341
- case types_1.QueryType.SPOTIFY_ALBUM: {
342
- const spotifyPlaylist = yield spotify_url_info_1.default.getData(query).catch(Util_1.Util.noop);
343
- if (!spotifyPlaylist)
344
- return { playlist: null, tracks: [] };
345
- const playlist = new Playlist_1.Playlist(this, {
346
- title: (_o = spotifyPlaylist.name) !== null && _o !== void 0 ? _o : spotifyPlaylist.title,
347
- description: (_p = spotifyPlaylist.description) !== null && _p !== void 0 ? _p : "",
348
- thumbnail: (_r = (_q = spotifyPlaylist.images[0]) === null || _q === void 0 ? void 0 : _q.url) !== null && _r !== void 0 ? _r : "https://www.scdn.co/i/_global/twitter_card-default.jpg",
349
- type: spotifyPlaylist.type,
350
- source: "spotify",
351
- author: spotifyPlaylist.type !== "playlist"
352
- ? {
353
- name: (_t = (_s = spotifyPlaylist.artists[0]) === null || _s === void 0 ? void 0 : _s.name) !== null && _t !== void 0 ? _t : "Unknown Artist",
354
- url: (_w = (_v = (_u = spotifyPlaylist.artists[0]) === null || _u === void 0 ? void 0 : _u.external_urls) === null || _v === void 0 ? void 0 : _v.spotify) !== null && _w !== void 0 ? _w : null
355
- }
356
- : {
357
- name: (_0 = (_y = (_x = spotifyPlaylist.owner) === null || _x === void 0 ? void 0 : _x.display_name) !== null && _y !== void 0 ? _y : (_z = spotifyPlaylist.owner) === null || _z === void 0 ? void 0 : _z.id) !== null && _0 !== void 0 ? _0 : "Unknown Artist",
358
- url: (_3 = (_2 = (_1 = spotifyPlaylist.owner) === null || _1 === void 0 ? void 0 : _1.external_urls) === null || _2 === void 0 ? void 0 : _2.spotify) !== null && _3 !== void 0 ? _3 : null
359
- },
360
- tracks: [],
361
- id: spotifyPlaylist.id,
362
- url: (_5 = (_4 = spotifyPlaylist.external_urls) === null || _4 === void 0 ? void 0 : _4.spotify) !== null && _5 !== void 0 ? _5 : query,
363
- rawPlaylist: spotifyPlaylist
413
+ return data;
364
414
  });
365
- if (spotifyPlaylist.type !== "playlist") {
366
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
367
- playlist.tracks = spotifyPlaylist.tracks.items.map((m) => {
368
- var _a, _b, _c, _d, _e, _f, _g, _h;
369
- const data = new Track_1.default(this, {
370
- title: (_a = m.name) !== null && _a !== void 0 ? _a : "",
371
- description: (_b = m.description) !== null && _b !== void 0 ? _b : "",
372
- author: (_d = (_c = m.artists[0]) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : "Unknown Artist",
373
- url: (_f = (_e = m.external_urls) === null || _e === void 0 ? void 0 : _e.spotify) !== null && _f !== void 0 ? _f : query,
374
- thumbnail: (_h = (_g = spotifyPlaylist.images[0]) === null || _g === void 0 ? void 0 : _g.url) !== null && _h !== void 0 ? _h : "https://www.scdn.co/i/_global/twitter_card-default.jpg",
375
- duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.duration_ms)),
376
- views: 0,
377
- requestedBy: options.requestedBy,
378
- playlist,
379
- source: "spotify"
380
- });
381
- return data;
382
- });
383
- }
384
- else {
385
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
386
- playlist.tracks = spotifyPlaylist.tracks.items.map((m) => {
387
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
388
- const data = new Track_1.default(this, {
389
- title: (_a = m.track.name) !== null && _a !== void 0 ? _a : "",
390
- description: (_b = m.track.description) !== null && _b !== void 0 ? _b : "",
391
- author: (_d = (_c = m.track.artists[0]) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : "Unknown Artist",
392
- url: (_f = (_e = m.track.external_urls) === null || _e === void 0 ? void 0 : _e.spotify) !== null && _f !== void 0 ? _f : query,
393
- thumbnail: (_j = (_h = (_g = m.track.album) === null || _g === void 0 ? void 0 : _g.images[0]) === null || _h === void 0 ? void 0 : _h.url) !== null && _j !== void 0 ? _j : "https://www.scdn.co/i/_global/twitter_card-default.jpg",
394
- duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(m.track.duration_ms)),
395
- views: 0,
396
- requestedBy: options.requestedBy,
397
- playlist,
398
- source: "spotify"
399
- });
400
- return data;
401
- });
402
- }
403
- return { playlist: playlist, tracks: playlist.tracks };
404
415
  }
405
- case types_1.QueryType.SOUNDCLOUD_PLAYLIST: {
406
- const data = yield soundcloud.getPlaylist(query).catch(Util_1.Util.noop);
407
- if (!data)
408
- return { playlist: null, tracks: [] };
409
- const res = new Playlist_1.Playlist(this, {
410
- title: data.title,
411
- description: (_6 = data.description) !== null && _6 !== void 0 ? _6 : "",
412
- thumbnail: (_7 = data.thumbnail) !== null && _7 !== void 0 ? _7 : "https://soundcloud.com/pwa-icon-192.png",
413
- type: "playlist",
416
+ return { playlist: playlist, tracks: playlist.tracks };
417
+ }
418
+ case types_1.QueryType.SOUNDCLOUD_PLAYLIST: {
419
+ const data = await soundcloud.getPlaylist(query).catch(Util_1.Util.noop);
420
+ if (!data)
421
+ return { playlist: null, tracks: [] };
422
+ const res = new Playlist_1.Playlist(this, {
423
+ title: data.title,
424
+ description: data.description ?? "",
425
+ thumbnail: data.thumbnail ?? "https://soundcloud.com/pwa-icon-192.png",
426
+ type: "playlist",
427
+ source: "soundcloud",
428
+ author: {
429
+ name: data.author?.name ?? data.author?.username ?? "Unknown Artist",
430
+ url: data.author?.profile
431
+ },
432
+ tracks: [],
433
+ id: `${data.id}`,
434
+ url: data.url,
435
+ rawPlaylist: data
436
+ });
437
+ for (const song of data.tracks) {
438
+ const track = new Track_1.default(this, {
439
+ title: song.title,
440
+ description: song.description ?? "",
441
+ author: song.author?.username ?? song.author?.name ?? "Unknown Artist",
442
+ url: song.url,
443
+ thumbnail: song.thumbnail,
444
+ duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(song.duration)),
445
+ views: song.playCount ?? 0,
446
+ requestedBy: options.requestedBy,
447
+ playlist: res,
414
448
  source: "soundcloud",
415
- author: {
416
- name: (_11 = (_9 = (_8 = data.author) === null || _8 === void 0 ? void 0 : _8.name) !== null && _9 !== void 0 ? _9 : (_10 = data.author) === null || _10 === void 0 ? void 0 : _10.username) !== null && _11 !== void 0 ? _11 : "Unknown Artist",
417
- url: (_12 = data.author) === null || _12 === void 0 ? void 0 : _12.profile
418
- },
419
- tracks: [],
420
- id: `${data.id}`,
421
- url: data.url,
422
- rawPlaylist: data
449
+ engine: song
423
450
  });
424
- for (const song of data.tracks) {
425
- const track = new Track_1.default(this, {
426
- title: song.title,
427
- description: (_13 = song.description) !== null && _13 !== void 0 ? _13 : "",
428
- author: (_17 = (_15 = (_14 = song.author) === null || _14 === void 0 ? void 0 : _14.username) !== null && _15 !== void 0 ? _15 : (_16 = song.author) === null || _16 === void 0 ? void 0 : _16.name) !== null && _17 !== void 0 ? _17 : "Unknown Artist",
429
- url: song.url,
430
- thumbnail: song.thumbnail,
431
- duration: Util_1.Util.buildTimeCode(Util_1.Util.parseMS(song.duration)),
432
- views: (_18 = song.playCount) !== null && _18 !== void 0 ? _18 : 0,
433
- requestedBy: options.requestedBy,
434
- playlist: res,
435
- source: "soundcloud",
436
- engine: song
437
- });
438
- res.tracks.push(track);
439
- }
440
- return { playlist: res, tracks: res.tracks };
441
- }
442
- case types_1.QueryType.YOUTUBE_PLAYLIST: {
443
- const ytpl = yield youtube_sr_1.default.getPlaylist(query).catch(Util_1.Util.noop);
444
- if (!ytpl)
445
- return { playlist: null, tracks: [] };
446
- yield ytpl.fetch().catch(Util_1.Util.noop);
447
- const playlist = new Playlist_1.Playlist(this, {
448
- title: ytpl.title,
449
- thumbnail: ytpl.thumbnail,
450
- description: "",
451
- type: "playlist",
452
- source: "youtube",
453
- author: {
454
- name: ytpl.channel.name,
455
- url: ytpl.channel.url
456
- },
457
- tracks: [],
458
- id: ytpl.id,
459
- url: ytpl.url,
460
- rawPlaylist: ytpl
461
- });
462
- playlist.tracks = ytpl.videos.map((video) => {
463
- var _a;
464
- return new Track_1.default(this, {
465
- title: video.title,
466
- description: video.description,
467
- author: (_a = video.channel) === null || _a === void 0 ? void 0 : _a.name,
468
- url: video.url,
469
- requestedBy: options.requestedBy,
470
- thumbnail: video.thumbnail.url,
471
- views: video.views,
472
- duration: video.durationFormatted,
473
- raw: video,
474
- playlist: playlist,
475
- source: "youtube"
476
- });
477
- });
478
- return { playlist: playlist, tracks: playlist.tracks };
451
+ res.tracks.push(track);
479
452
  }
480
- default:
453
+ return { playlist: res, tracks: res.tracks };
454
+ }
455
+ case types_1.QueryType.YOUTUBE_PLAYLIST: {
456
+ const ytpl = await youtube_sr_1.default.getPlaylist(query).catch(Util_1.Util.noop);
457
+ if (!ytpl)
481
458
  return { playlist: null, tracks: [] };
459
+ await ytpl.fetch().catch(Util_1.Util.noop);
460
+ const playlist = new Playlist_1.Playlist(this, {
461
+ title: ytpl.title,
462
+ thumbnail: ytpl.thumbnail,
463
+ description: "",
464
+ type: "playlist",
465
+ source: "youtube",
466
+ author: {
467
+ name: ytpl.channel.name,
468
+ url: ytpl.channel.url
469
+ },
470
+ tracks: [],
471
+ id: ytpl.id,
472
+ url: ytpl.url,
473
+ rawPlaylist: ytpl
474
+ });
475
+ playlist.tracks = ytpl.videos.map((video) => new Track_1.default(this, {
476
+ title: video.title,
477
+ description: video.description,
478
+ author: video.channel?.name,
479
+ url: video.url,
480
+ requestedBy: options.requestedBy,
481
+ thumbnail: video.thumbnail.url,
482
+ views: video.views,
483
+ duration: video.durationFormatted,
484
+ raw: video,
485
+ playlist: playlist,
486
+ source: "youtube"
487
+ }));
488
+ return { playlist: playlist, tracks: playlist.tracks };
482
489
  }
483
- });
490
+ default:
491
+ return { playlist: null, tracks: [] };
492
+ }
484
493
  }
485
494
  /**
486
495
  * Registers extractor