diff --git a/bot.js b/bot.js index d3dc8a5..9dc1a97 100644 --- a/bot.js +++ b/bot.js @@ -66,6 +66,7 @@ function registerCommands() { cmd.createCommand('~', 'plist', (msg) => { let gid = msg.guild.id; let songs = music.getQueue(gid); + logger.debug(`found ${songs.length} songs`); let songlist = "**Songs**\n"; for (let i = 0; i < songs.length; i++) { if (i > 10) break; diff --git a/lib/music.js b/lib/music.js index 89636e1..0dd5efe 100644 --- a/lib/music.js +++ b/lib/music.js @@ -22,7 +22,16 @@ class DJ { this.voiceChannel = voiceChannel; } + /** + * Connects to the given voice channel. Disconnects from the previous one if it exists. + * When the bot was moved and connect is executed again, it connects to the initial VoiceChannel because the + * VoiceChannel is saved as object variable. + * @returns {Promise} + */ connect() { + if (this.conn) { + this.stop(); + } logger.verbose(`Connecting to voiceChannel ${this.voiceChannel.name}`); return this.voiceChannel.join().then(connection => { logger.info(`Connected to Voicechannel ${this.voiceChannel.name}`); @@ -30,6 +39,11 @@ class DJ { }); } + /** + * Plays a file for the given filename. + * TODO: Implement queue + * @param filename + */ playFile(filename) { if (this.conn !== null) { this.disp = this.conn.playFile(filename); @@ -42,6 +56,12 @@ class DJ { } } + /** + * Plays the url of the current song if there is no song playing or puts it in the queue. + * If the url is a playlist (regex match), the videos of the playlist are fetched and put + * in the queue. For each song the title is saved in the queue too. + * @param url + */ playYouTube(url) { if (!this.conn) this.connect(this.voiceChannel).then(this.playYouTube(url)); let plist = url.match(/(?<=\?list=)[\w\-]+/g); @@ -55,13 +75,19 @@ class DJ { if (err) { logger.error(err); } else { - this.queue.find((el) => { - return (el.url === vurl); - }).title = title; + try { + logger.debug(`Found title: ${title} for ${vurl}`); + this.queue.find((el) => { + return (el.url === vurl); + }).title = title; + } catch (error) { + logger.error(JSON.stringify(error)); + } } }); } - this.playYouTube(this.queue.shift().url); + this.current = this.queue.shift(); + this.playYouTube(this.current.url); }); return; } @@ -74,7 +100,7 @@ class DJ { this.playing = false; this.current = null; if (this.queue.length > 0) { - this.current = this.queue.shift() + this.current = this.queue.shift(); this.playYouTube(this.current.url); } else { this.stop(); @@ -83,19 +109,41 @@ class DJ { this.playing = true; } else { logger.debug(`Added ${url} to the queue`); - this.queue.push(url); + this.queue.push({'url': url, 'title': null}); + yttl(url.replace(/http(s)?:\/\/(www.)?youtube.com\/watch\?v=/g, ''), (err, title) => { + if (err) { + logger.error(err); + } else { + try { + logger.debug(`Found title: ${title} for ${url}`); + this.queue.find((el) => { + return (el.url === url); + }).title = title; + } catch (error) { + console.error(JSON.stringify(error)); + } + } + }); } } + /** + * Sets the volume of the dispatcher to the given value + * @param percentage + */ setVolume(percentage) { logger.verbose(`Setting volume to ${percentage}`); if (this.disp !== null) { + this.volume = percentage; this.disp.setVolume(percentage); } else { logger.warn("No dispatcher found.") } } + /** + * Pauses if a dispatcher exists + */ pause() { logger.verbose("Pausing music..."); if (this.disp !== null) { @@ -105,6 +153,9 @@ class DJ { } } + /** + * Resumes if a dispatcher exists + */ resume() { logger.verbose("Resuming music..."); if (this.disp !== null) { @@ -114,7 +165,11 @@ class DJ { } } + /** + * Stops playing music by ending the Dispatcher and disconnecting + */ stop() { + this.queue = []; logger.verbose("Stopping music..."); if (this.disp !== null) { this.disp.end(); @@ -126,6 +181,10 @@ class DJ { } } + /** + * Skips to the next song by ending the current StreamDispatcher and thereby triggering the + * end event of the dispatcher that automatically plays the next song. + */ skip () { logger.debug("Skipping song"); if (this.disp !== null) { @@ -133,18 +192,30 @@ class DJ { } } + /** + * Returns the title for each song saved in the queue + * @returns {Array} + */ get playlist() { let songs = []; + logger.debug(`Playlist: ${JSON.stringify(this.queue)}`); this.queue.forEach((entry) => { songs.push(entry.title); }); return songs; } + /** + * Returns the song saved in the private variable 'current' + * @returns {null|*} + */ get song() { - return this.current.title; + return this.current; } + /** + * Shuffles the queue + */ shuffle() { this.queue = shuffleArray(this.queue); }