diff --git a/commands/music/play.js b/commands/music/play.js index 9fea22c..5b3669c 100644 --- a/commands/music/play.js +++ b/commands/music/play.js @@ -59,24 +59,20 @@ module.exports = class Play extends Command { playlistVideos.forEach(async playlistVideo => { const video = await youtube.getVideoByID(playlistVideo.id); - - const title = video.title; - const by = video.channel.title; - const durationString = message.guild.formatDurationString(video.duration); - const thumbnail = video.thumbnails.high.url; + const durationString = message.guild.formatDurationString(video.duration.hours, video.duration.minutes, video.duration.seconds); const data = { type: 'youtube', link: `https://www.youtube.com/watch?v=${video.id}`, - title, - by, - duration: durationString !== '00:00:00' ? { hours: video.duration.hours, minutes: video.duration.minutes, seconds: video.duration.seconds, string: durationString } : 'Live Stream', - thumbnail, + title: video.title, + by: video.channel.title, + duration: durationString !== '00:00:00' ? durationString : 'Live Stream', + thumbnail: video.thumbnails.high.url, voiceChannel }; message.guild.music.queue.push(data); - if (message.guild.music.isPlaying === false || message.guild.music.isPlaying === undefined) { + if (!message.guild.music.isPlaying) { message.guild.music.isPlaying = true; return message.guild.play(message.guild.music.queue, message); } @@ -88,26 +84,21 @@ module.exports = class Play extends Command { } else if (query.match(/^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/\S+/)) { const link = query.match(/^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/\S+/)[0]; const id = link.replace(/(>|<)/gi, '').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/)[2].split(/[^0-9a-z_\-]/i)[0]; - const video = await youtube.getVideoByID(id); - const title = video.title; - const by = video.channel.title; - const durationString = message.guild.formatDurationString(video.duration); - const thumbnail = video.thumbnails.high.url; - + const durationString = message.guild.formatDurationString(video.duration.hours, video.duration.minutes, video.duration.seconds); const data = { type: 'youtube', link, - title, - by, - duration: durationString !== '00:00:00' ? { hours: video.duration.hours, minutes: video.duration.minutes, seconds: video.duration.seconds, string: durationString } : 'Live Stream', - thumbnail, + title: video.title, + by: video.channel.title, + duration: durationString !== '00:00:00' ? durationString : 'Live Stream', + thumbnail: video.thumbnails.high.url, voiceChannel }; message.guild.music.queue.push(data); - if (message.guild.music.isPlaying === false || message.guild.music.isPlaying === undefined) { + if (!message.guild.music.isPlaying) { message.guild.music.isPlaying = true; return message.guild.play(message.guild.music.queue, message); } else { @@ -116,10 +107,7 @@ module.exports = class Play extends Command { } } else if (query.match(/^(http(s)?:\/\/)?((w){3}.)?facebook?(\.com)?\/\S+\/videos\/\S+/)) { const link = query.match(/^(http(s)?:\/\/)?((w){3}.)?facebook?(\.com)?\/\S+\/videos\/\S+/)[0]; - - const browser = await puppeteer.launch({ - timeout: 0 - }); + const browser = await puppeteer.launch({ timeout: 0 }); const page = await browser.newPage(); page.setDefaultNavigationTimeout(0); @@ -142,7 +130,7 @@ module.exports = class Play extends Command { }); } - const durationString = durationArr ? message.guild.formatDurationString({ hours: durationArr[0], minutes: durationArr[1], seconds: durationArr[2] + 1 }) : 'Live Stream'; + const durationString = durationArr ? message.guild.formatDurationString(durationArr[0], durationArr[1], durationArr[2] + 1) : 'Live Stream'; const title = await page.evaluate(title => title.innerText.replace(/\s\|\sfacebook/i, ''), titleHandle); const videoLink = await page.evaluate(meta => meta.getAttribute('content'), metaHandle); const data = { @@ -150,13 +138,13 @@ module.exports = class Play extends Command { link: videoLink, title: title.split(' - ')[1], by: title.split(' - ')[0], - duration: durationString !== 'Live Stream' ? { hours: durationArr[0], minutes: durationArr[1], seconds: durationArr[2] + 1, string: durationString } : durationString, + duration: durationString, voiceChannel }; message.guild.music.queue.push(data); - if (message.guild.music.isPlaying === false || message.guild.music.isPlaying === undefined) { + if (!message.guild.music.isPlaying) { message.guild.music.isPlaying = true; return message.guild.play(message.guild.music.queue, message); } else { @@ -169,63 +157,55 @@ module.exports = class Play extends Command { ffmpeg.ffprobe(link, async(err, metaData) => { if (err) throw err; - else { - const duration = { - hours: new Date(Math.ceil(metaData.format.duration) * 1000).getUTCHours(), - minutes: new Date(Math.ceil(metaData.format.duration) * 1000).getUTCMinutes(), - seconds: new Date(Math.ceil(metaData.format.duration) * 1000).getSeconds(), - string: message.guild.formatDurationString({ - hours: new Date(Math.ceil(metaData.format.duration) * 1000).getUTCHours(), - minutes: new Date(Math.ceil(metaData.format.duration) * 1000).getUTCMinutes(), - seconds: new Date(Math.ceil(metaData.format.duration) * 1000).getSeconds() - }) - }; - const data = { - type: 'other', - link, - title, - duration, - voiceChannel - }; + const duration = message.guild.formatDurationString( + new Date(Math.ceil(metaData.format.duration) * 1000).getUTCHours(), + new Date(Math.ceil(metaData.format.duration) * 1000).getUTCMinutes(), + new Date(Math.ceil(metaData.format.duration) * 1000).getSeconds() + ); - if (data) { - message.guild.music.queue.push(data); + const data = { + type: 'other', + link, + title, + duration, + voiceChannel + }; - if (message.guild.music.isPlaying === false || message.guild.music.isPlaying === undefined) { - message.guild.music.isPlaying = true; - return message.guild.play(message.guild.music.queue, message); - } else { - const embed = new MessageEmbed().setColor('#000099').setTitle(`:arrow_forward: Added "${data.title}" to queue`); - return await message.say({ embed }); - } + if (data) { + message.guild.music.queue.push(data); + + if (!message.guild.music.isPlaying) { + message.guild.music.isPlaying = true; + return message.guild.play(message.guild.music.queue, message); + } else { + const embed = new MessageEmbed().setColor('#000099').setTitle(`:arrow_forward: Added "${data.title}" to queue`); + return await message.say({ embed }); } } }); } else { const videos = await youtube.searchVideos(query, 1); + if (videos.length !== 1) { const embed = new MessageEmbed().setColor('#ff0000').setTitle(':x: Nothing found'); return await message.say({ embed }); } const video = await youtube.getVideoByID(videos[0].raw.id.videoId); - const title = video.title; - const by = video.channel.title; - const durationString = message.guild.formatDurationString(video.duration); - const thumbnail = video.thumbnails.high.url; + const durationString = message.guild.formatDurationString(video.duration.hours, video.duration.minutes, video.duration.seconds); const data = { - type: 'search', + type: 'youtube', link: `https://www.youtube.com/watch?v=${video.id}`, - title, - by, - duration: durationString !== '00:00:00' ? { hours: video.duration.hours, minutes: video.duration.minutes, seconds: video.duration.seconds, string: durationString } : 'Live Stream', - thumbnail, + title: video.title, + by: video.channel.title, + duration: durationString !== '00:00:00' ? durationString : 'Live Stream', + thumbnail: video.thumbnails.high.url, voiceChannel }; message.guild.music.queue.push(data); - if (message.guild.music.isPlaying === false || message.guild.music.isPlaying === undefined) { + if (!message.guild.music.isPlaying) { message.guild.music.isPlaying = true; return message.guild.play(message.guild.music.queue, message); } else { @@ -235,7 +215,7 @@ module.exports = class Play extends Command { } } catch(err) { logger.log('error', err); - const embed = new MessageEmbed().setColor('#ff0000').setTitle(':x: Track is private or I just can\'t play this for some other reason'); + const embed = new MessageEmbed().setColor('#ff0000').setTitle(':x: Cannot play this track'); return message.say({ embed }); } } diff --git a/commands/music/queue.js b/commands/music/queue.js index 1d48674..b38c5d2 100644 --- a/commands/music/queue.js +++ b/commands/music/queue.js @@ -34,10 +34,10 @@ module.exports = class Play extends Command { return await message.say({ embed }); } else { const embed = new MessageEmbed().setColor('#000099').setTitle(':musical_note: Queue'); + const time = message.guild.music.seek ? message.guild.music.dispatcher.streamTime + message.guild.music.seek * 1000 : message.guild.music.dispatcher.streamTime; + const timeString = message.guild.formatDurationString(new Date(time).getUTCHours(), new Date(time).getUTCMinutes(), new Date(time).getSeconds()); - embed - .addField('Now playing', `${message.guild.music.nowPlaying.title} ${message.guild.music.nowPlaying.by && `By ${message.guild.music.nowPlaying.by}`}`) - .addField('Duration', `${message.guild.music.nowPlaying.playingFor.string}/${message.guild.music.nowPlaying.duration.string}`); + embed.addField('Now playing', message.guild.music.nowPlaying.title).addField('Duration', `${timeString}/${message.guild.music.nowPlaying.duration}`); if (message.guild.music.queue.length === 0) embed.addField('Queue', 'nothing in the queue'); else embed.addField('Queue', `${message.guild.music.queue.length} track(s)`); diff --git a/commands/music/search.js b/commands/music/search.js index abda520..fc46e88 100644 --- a/commands/music/search.js +++ b/commands/music/search.js @@ -78,17 +78,14 @@ module.exports = class JoinCommand extends Command { } const video = await youtube.getVideoByID(videos[index - 1].raw.id.videoId); - const title = video.title; - const by = video.channel.title; - const durationString = message.guild.formatDurationString(video.duration); - const thumbnail = video.thumbnails.high.url; + const durationString = message.guild.formatDurationString(video.duration.hours, video.duration.minutes, video.duration.seconds); const data = { - type: 'search', + type: 'youtube', link: `https://www.youtube.com/watch?v=${video.id}`, - title, - by, - duration: durationString !== '00:00:00' ? { hours: video.duration.hours, minutes: video.duration.minutes, seconds: video.duration.seconds, string: durationString } : 'Live Stream', - thumbnail, + title: video.title, + by: video.channel.title, + duration: durationString !== '00:00:00' ? durationString : 'Live Stream', + thumbnail: video.thumbnails.high.url, voiceChannel }; diff --git a/commands/music/seek.js b/commands/music/seek.js index ae4a7e0..7e57754 100644 --- a/commands/music/seek.js +++ b/commands/music/seek.js @@ -25,7 +25,7 @@ module.exports = class JoinCommand extends Command { key: 'query', prompt: 'to what time do you want to seek? (HH:MM:SS)', type: 'string', - validate: query => query.length > 0 && query.match(/(\d+:)?\d{2}:\d{2}/) + validate: query => query.length > 0 && query.match(/\d+:\d{2}:\d{2}/) } ], throttling: { @@ -46,15 +46,13 @@ module.exports = class JoinCommand extends Command { return await message.say({ embed }); } else { - const seekDuration = message.guild.formatDurationObject(query); - const seekSeconds = seekDuration.hours * 3600 + seekDuration.minutes * 60 + seekDuration.seconds; - const nowplayingSeconds = message.guild.music.nowPlaying.duration.hours * 3600 + message.guild.music.nowPlaying.duration.minutes * 60 + message.guild.music.nowPlaying.duration.seconds; + const seekSeconds = message.guild.formatDurationSeconds(query); + const nowplayingSeconds = message.guild.formatDurationSeconds(message.guild.music.nowPlaying.duration); if (seekSeconds > nowplayingSeconds) { const embed = new MessageEmbed().setColor('#ff0000').setTitle(':x: Seek time is greater than track time'); return await message.say({ embed }); } message.guild.music.seek = seekSeconds; - message.guild.music.nowPlaying.playingFor = { hours: seekDuration.hours, minutes: seekDuration.minutes, seconds: seekDuration.seconds, string: message.guild.formatDurationString(seekDuration) }; await message.guild.play(message.guild.music.queue, message); const embed = new MessageEmbed().setColor('#000099').setTitle(`:musical_note: Sought to ${query}`); return await message.say({ embed }); diff --git a/commands/music/stop.js b/commands/music/stop.js index ff3350e..85dde19 100644 --- a/commands/music/stop.js +++ b/commands/music/stop.js @@ -42,6 +42,7 @@ module.exports = class Play extends Command { message.guild.music.isPlaying = false; message.guild.music.nowPlaying = null; message.guild.music.dispatcher = null; + message.guild.music.seek = null; message.guild.music.queue = []; voiceChannel.leave(); const embed = new MessageEmbed().setColor('#000099').setTitle(':stop_button: Stopped player and cleared queue'); diff --git a/index.js b/index.js index 383c15c..d133017 100644 --- a/index.js +++ b/index.js @@ -34,44 +34,38 @@ Structures.extend('Guild', Guild => { play = async (queue, message) => { try { - if (!message.guild.music.seek && queue.length === 0) { - const embed = new MessageEmbed().setColor('#ff0000').setTitle(`:x: Error occured: ${err.message}`); - return await message.say({ embed }); - } + if (!message.guild.music.seek && queue.length === 0) throw new Error('Unknwon'); const voiceChannel = !message.guild.music.seek ? queue[0].voiceChannel : message.guild.music.nowPlaying.voiceChannel; const connection = await voiceChannel.join(); + let dispatcher; if (message.guild.music.seek) { switch (message.guild.music.nowPlaying.type) { case 'youtube': { dispatcher = connection.play(ytdl(message.guild.music.nowPlaying.link, { quality: 'highestaudio' }), { seek: message.guild.music.seek }); break; } case 'facebook': { dispatcher = connection.play(message.guild.music.nowPlaying.link, { seek: message.guild.music.seek }); break; } - case 'search': { dispatcher = connection.play(ytdl(message.guild.music.nowPlaying.link, { quality: 'highestaudio' }), { seek: message.guild.music.seek }); break; } case 'other': { dispatcher = connection.play(message.guild.music.nowPlaying.link, { seek: message.guild.music.seek }); break; } } } else { switch (queue[0].type) { case 'youtube': { dispatcher = connection.play(ytdl(queue[0].link, { quality: 'highestaudio' })); break; } case 'facebook': { dispatcher = connection.play(queue[0].link); break; } - case 'search': { dispatcher = connection.play(ytdl(queue[0].link, { quality: 'highestaudio' })); break; } case 'other': { dispatcher = connection.play(queue[0].link); break; } } } dispatcher.on('start', async () => { message.guild.music.nowPlaying = !message.guild.music.seek ? queue[0] : message.guild.music.nowPlaying; - message.guild.startCounter(message); message.guild.music.dispatcher = dispatcher; dispatcher.setVolume(message.guild.music.volume); if (!message.guild.music.seek) { const embed = new MessageEmbed().setColor('#000099').setTitle(`:arrow_forward: Play`).addField('Now playing', queue[0].title); - if (queue[0].type === 'youtube' || queue[0].type === 'search') embed.setThumbnail(queue[0].thumbnail); - if (queue[0].type === 'youtube' || queue[0].type === 'search' || queue[0].type === 'facebook') embed.addField('By', queue[0].by); - embed.addField('Duration', queue[0].duration.string); + if (queue[0].type === 'youtube') embed.setThumbnail(queue[0].thumbnail); + if (queue[0].type !== 'other') embed.addField('By', queue[0].by); + embed.addField('Duration', queue[0].duration); await message.say({ embed }); } - message.guild.music.seek = null; return queue.shift(); }); @@ -80,15 +74,13 @@ Structures.extend('Guild', Guild => { message.guild.music.seek = null; return this.play(queue, message); } - else { - message.guild.music.isPlaying = false; - message.guild.music.nowPlaying = null; - message.guild.music.dispatcher = null; - message.guild.music.seek = null; - voiceChannel.leave(); - const embed = new MessageEmbed().setColor('#000099').setTitle(':musical_note: Queue ended'); - return await message.say({ embed }); - } + message.guild.music.isPlaying = false; + message.guild.music.nowPlaying = null; + message.guild.music.dispatcher = null; + message.guild.music.seek = null; + voiceChannel.leave(); + const embed = new MessageEmbed().setColor('#000099').setTitle(':musical_note: Queue ended'); + return await message.say({ embed }); }); dispatcher.on('error', err => { @@ -107,69 +99,16 @@ Structures.extend('Guild', Guild => { } } - startCounter = message => { - try { - if (!message.guild.music.nowPlaying.playingFor) message.guild.music.nowPlaying.playingFor = { hours: 0, minutes: 0, seconds: 0, string: '00:00:00' }; - - const interval = setInterval(() => { - if (!message.guild.music.nowPlaying || message.guild.music.paused) clearInterval(interval); - else if (message.guild.music.nowPlaying.playingFor.seconds === 60) { - message.guild.music.nowPlaying.playingFor = { - hours: message.guild.music.nowPlaying.playingFor.hours, - minutes: message.guild.music.nowPlaying.playingFor.minutes + 1, - seconds: 0, - string: this.formatDurationString({ - hours: message.guild.music.nowPlaying.playingFor.hours, - minutes: message.guild.music.nowPlaying.playingFor.minutes + 1, - seconds: 0 - }) - }; - } - else if (message.guild.music.nowPlaying.playingFor.minutes === 60) { - message.guild.music.nowPlaying.playingFor = { - hours: message.guild.music.nowPlaying.playingFor.hours + 1, - minutes: 0, - seconds: 0, - string: this.formatDurationString({ - hours: message.guild.music.nowPlaying.playingFor.hours + 1, - minutes: 0, - seconds: 0 - }) - }; - } - else { - message.guild.music.nowPlaying.playingFor = { - hours: message.guild.music.nowPlaying.playingFor.hours, - minutes: message.guild.music.nowPlaying.playingFor.minutes, - seconds: message.guild.music.nowPlaying.playingFor.seconds + 1, - string: this.formatDurationString({ - hours: message.guild.music.nowPlaying.playingFor.hours, - minutes: message.guild.music.nowPlaying.playingFor.minutes, - seconds: message.guild.music.nowPlaying.playingFor.seconds + 1 - }) - }; - } - }, 1000); - } catch(err) { - logger.log('error', err); - const embed = new MessageEmbed().setColor('#ff0000').setTitle(`:x: Error occured: ${err.message}`); - return message.say({ embed }); - } + formatDurationString = (hours, minutes, seconds) => { + return `${hours < 10 ? '0' + hours : hours ? hours : '00'}:${minutes < 10 ? '0' + minutes : minutes ? minutes : '00'}:${seconds < 10 ? '0' + seconds : seconds ? seconds : '00'}`; } - formatDurationString = durationObject => { - return `${durationObject.hours < 10 ? '0' + durationObject.hours : durationObject.hours ? durationObject.hours : '00'}:${durationObject.minutes < 10 ? '0' + durationObject.minutes : durationObject.minutes ? durationObject.minutes : '00'}:${durationObject.seconds < 10 ? '0' + durationObject.seconds : durationObject.seconds ? durationObject.seconds : '00'}`; - } + formatDurationSeconds = durationString => { + if (!durationString.match(/\d+:\d{2}:\d{2}/)) return; + + const time = durationString.split(':').map(time => parseInt(time)); - formatDurationObject = durationString => { - if (!durationString.match(/(\d+:)?\d{2}:\d{2}/)) return; - const time = durationString.split(':').map(t => parseInt(t)); - - switch(time.length) { - case 3: return { hours: time[0], minutes: time[1], seconds: time[2] }; - case 2: return { hours: 0, minutes: time[0], seconds: time[1] }; - case 1: return { hours: 0, minutes: 0, seconds: time[0] }; - } + return time[0] * 3600 + time[1] * 60 + time[2]; } }