✨ Support for Spotify playlists and albums (#226)
This commit is contained in:
parent
6d53e02e74
commit
15e223a50e
2 changed files with 75 additions and 1 deletions
|
@ -141,6 +141,8 @@ class Player extends EventEmitter {
|
|||
return 'youtube-video'
|
||||
} else if (this.util.isSoundcloudLink(query)) {
|
||||
return 'soundcloud-song'
|
||||
} else if (this.util.isSpotifyPLLink(query)) {
|
||||
return 'spotify-playlist'
|
||||
} else {
|
||||
return 'youtube-video-keywords'
|
||||
}
|
||||
|
@ -331,7 +333,63 @@ class Player extends EventEmitter {
|
|||
this._addTracksToQueue(message, playlist.tracks)
|
||||
}
|
||||
}
|
||||
|
||||
async _handleSpotifyPlaylist (message, query) {
|
||||
const playlist = await spotify.getData(query)
|
||||
if (!playlist) return this.emit('noResults', message, query)
|
||||
let tracks = []
|
||||
let s;
|
||||
for (var i = 0; i < playlist.tracks.items.length; i++) {
|
||||
let query = `${playlist.tracks.items[i].track.artists[0].name} - ${playlist.tracks.items[i].track.name}`
|
||||
let results = await ytsr.search(query, { type: 'video' })
|
||||
if (results.length < 1) {
|
||||
s++ // could be used later for skipped tracks due to result not being found
|
||||
continue;
|
||||
}
|
||||
tracks.push(results[0])
|
||||
}
|
||||
playlist.tracks = tracks.map((item) => new Track(item, message.author))
|
||||
playlist.duration = playlist.tracks.reduce((prev, next) => prev + next.duration, 0)
|
||||
playlist.thumbnail = playlist.images[0].url
|
||||
playlist.requestedBy = message.author
|
||||
if (this.isPlaying(message)) {
|
||||
const queue = this._addTracksToQueue(message, playlist.tracks)
|
||||
this.emit('playlistAdd', message, queue, playlist)
|
||||
} else {
|
||||
const track = playlist.tracks.shift()
|
||||
const queue = await this._createQueue(message, track).catch((e) => this.emit('error', e, message))
|
||||
this.emit('trackStart', message, queue.tracks[0])
|
||||
this._addTracksToQueue(message, playlist.tracks)
|
||||
}
|
||||
}
|
||||
async _handleSpotifyAlbum (message, query) {
|
||||
const album = await spotify.getData(query)
|
||||
if (!album) return this.emit('noResults', message, query)
|
||||
let tracks = []
|
||||
let s;
|
||||
for (var i = 0; i < album.tracks.items.length; i++) {
|
||||
let query = `${album.tracks.items[i].artists[0].name} - ${album.tracks.items[i].name}`
|
||||
let results = await ytsr.search(query, { type: 'video' })
|
||||
if (results.length < 1) {
|
||||
s++ // could be used later for skipped tracks due to result not being found
|
||||
continue;
|
||||
}
|
||||
tracks.push(results[0])
|
||||
}
|
||||
|
||||
album.tracks = tracks.map((item) => new Track(item, message.author))
|
||||
album.duration = album.tracks.reduce((prev, next) => prev + next.duration, 0)
|
||||
album.thumbnail = album.images[0].url
|
||||
album.requestedBy = message.author
|
||||
if (this.isPlaying(message)) {
|
||||
const queue = this._addTracksToQueue(message, album.tracks)
|
||||
this.emit('playlistAdd', message, queue, album)
|
||||
} else {
|
||||
const track = album.tracks.shift()
|
||||
const queue = await this._createQueue(message, track).catch((e) => this.emit('error', e, message))
|
||||
this.emit('trackStart', message, queue.tracks[0])
|
||||
this._addTracksToQueue(message, album.tracks)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Play a track in the server. Supported query types are `keywords`, `YouTube video links`, `YouTube playlists links`, `Spotify track link` or `SoundCloud song link`.
|
||||
* @param {Discord.Message} message Discord `message`
|
||||
|
@ -346,6 +404,12 @@ class Player extends EventEmitter {
|
|||
if (this.util.isYTPlaylistLink(query)) {
|
||||
return this._handlePlaylist(message, query)
|
||||
}
|
||||
if (this.util.isSpotifyPLLink(query)) {
|
||||
return this._handleSpotifyPlaylist(message, query)
|
||||
}
|
||||
if (this.util.isSpotifyAlbumLink(query)) {
|
||||
return this._handleSpotifyAlbum(message, query)
|
||||
}
|
||||
let trackToPlay
|
||||
if (query instanceof Track) {
|
||||
trackToPlay = query
|
||||
|
|
10
src/Util.js
10
src/Util.js
|
@ -2,6 +2,8 @@ const ytsr = require('youtube-sr')
|
|||
const soundcloud = require('soundcloud-scraper')
|
||||
|
||||
const spotifySongRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/)
|
||||
const spotifyPlaylistRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/)
|
||||
const spotifyAlbumRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/)
|
||||
|
||||
module.exports = class Util {
|
||||
constructor () {
|
||||
|
@ -20,6 +22,14 @@ module.exports = class Util {
|
|||
return spotifySongRegex.test(query)
|
||||
}
|
||||
|
||||
static isSpotifyPLLink (query) {
|
||||
return spotifyPlaylistRegex.test(query)
|
||||
}
|
||||
|
||||
static isSpotifyAlbumLink(query) {
|
||||
return spotifyAlbumRegex.test(query)
|
||||
}
|
||||
|
||||
static isYTPlaylistLink (query) {
|
||||
return ytsr.validate(query, 'PLAYLIST')
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue