✨ 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'
|
return 'youtube-video'
|
||||||
} else if (this.util.isSoundcloudLink(query)) {
|
} else if (this.util.isSoundcloudLink(query)) {
|
||||||
return 'soundcloud-song'
|
return 'soundcloud-song'
|
||||||
|
} else if (this.util.isSpotifyPLLink(query)) {
|
||||||
|
return 'spotify-playlist'
|
||||||
} else {
|
} else {
|
||||||
return 'youtube-video-keywords'
|
return 'youtube-video-keywords'
|
||||||
}
|
}
|
||||||
|
@ -331,7 +333,63 @@ class Player extends EventEmitter {
|
||||||
this._addTracksToQueue(message, playlist.tracks)
|
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`.
|
* 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`
|
* @param {Discord.Message} message Discord `message`
|
||||||
|
@ -346,6 +404,12 @@ class Player extends EventEmitter {
|
||||||
if (this.util.isYTPlaylistLink(query)) {
|
if (this.util.isYTPlaylistLink(query)) {
|
||||||
return this._handlePlaylist(message, 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
|
let trackToPlay
|
||||||
if (query instanceof Track) {
|
if (query instanceof Track) {
|
||||||
trackToPlay = query
|
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 soundcloud = require('soundcloud-scraper')
|
||||||
|
|
||||||
const spotifySongRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/)
|
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 {
|
module.exports = class Util {
|
||||||
constructor () {
|
constructor () {
|
||||||
|
@ -20,6 +22,14 @@ module.exports = class Util {
|
||||||
return spotifySongRegex.test(query)
|
return spotifySongRegex.test(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isSpotifyPLLink (query) {
|
||||||
|
return spotifyPlaylistRegex.test(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
static isSpotifyAlbumLink(query) {
|
||||||
|
return spotifyAlbumRegex.test(query)
|
||||||
|
}
|
||||||
|
|
||||||
static isYTPlaylistLink (query) {
|
static isYTPlaylistLink (query) {
|
||||||
return ytsr.validate(query, 'PLAYLIST')
|
return ytsr.validate(query, 'PLAYLIST')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue