Last active
May 4, 2020 13:22
-
-
Save acrylic-style/c8d50d3ccf0c5124e6fabb22f549678e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ytdl = require('ytdl-core-discord') | |
const logger = require('logger.js').LoggerFactory.getLogger('commands:music') | |
const isNumber = (n) => !isNaN(parseFloat(n)) && isFinite(n) | |
const f = require('string-format') | |
const { Command } = require('bot-framework') | |
const YouTube = require('youtube-node') | |
const youtube = new YouTube() | |
const util = require('util') | |
const queue = {} | |
const playing = {} | |
const loop = {} | |
const play = async (connection, url, msg) => { | |
if (!loop[msg.guild.id]) loop[msg.guild.id] = {} | |
playing[msg.guild.id] = url | |
return connection.play(await ytdl(url, { filter: 'audioonly' }), { type: 'opus', seek: 0, volume: 0.1 }) // oldvalue: 0.1 | |
//return play2(connection, url) | |
} | |
module.exports = class extends Command { | |
constructor() { | |
const opts = { | |
args: [ | |
'play|start <URL or Search>', | |
'stop', | |
'pause', | |
'unpause|resume', | |
'volume', | |
'loop [disable|every [clear]]', | |
'queue', | |
'status', | |
], | |
alias: [ | |
'play', | |
], | |
} | |
super('music', opts) | |
} | |
async run(msg, lang, args, sendDeletable, prefix) { | |
if (!msg.member.voice) return await msg.channel.send(lang.COMMAND_MUSIC_NOT_JOINED_VC) | |
if (!loop[msg.guild.id]) loop[msg.guild.id] = {} // need initialize! | |
if (args[1] === 'join') { | |
msg.member.voice.channel.join().then(vc => msg.channel.send(f(lang.COMMAND_MUSIC_JOINED_VC, vc.channel.name))).catch(e => logger.error(e)) | |
} else if (args[1] === 'play' || args[1] === 'start') { | |
let keyword | |
if (!args[2] || !args[2].includes('youtube.com/watch?v=')) { | |
youtube.setKey(process.env.YOUTUBE_APIKEY) | |
const search = util.promisify(youtube.search) | |
const { items } = await search(args.slice(2).join(' '), 1).catch(e => logger.error(e)) | |
keyword = args.slice(2).join(' ') | |
args[2] = 'https://youtube.com/watch?v=' + items[0].id.videoId // ugly hack :( | |
} | |
msg.member.voice.channel.join() | |
.then(async connection => { | |
if (msg.guild.voice.connection && msg.guild.voice.connection.dispatcher && !msg.guild.voice.connection.dispatcher.destroyed) { | |
if (loop[msg.guild.id].enabled) return msg.channel.send(lang.COMMAND_MUSIC_CANTADD_LOOP_ENABLED) | |
if (!queue[msg.guild.id]) queue[msg.guild.id] = [] | |
queue[msg.guild.id].push(args[2]) | |
msg.channel.send(f(lang.COMMAND_MUSIC_QUEUE_ADDED, args[2])) | |
if (keyword) msg.channel.send('検索キーワード: ' + keyword) | |
} else { | |
await play(connection, args[2], msg) | |
msg.channel.send(f(lang.COMMAND_MUSIC_PLAYING, args[2])) | |
if (keyword) msg.channel.send('検索キーワード: ' + keyword) | |
} | |
if (msg.deletable) msg.delete() | |
const endHandler = async () => { | |
const q = queue[msg.guild.id] | |
if (q && (q ? q.length : false) && !loop[msg.guild.id].enabled) { // if queue is *not* empty and not enabled loop | |
await play(connection, q[0], msg) | |
msg.channel.send(f(lang.COMMAND_MUSIC_PLAYING_QUEUE, q[0])) | |
queue[msg.guild.id] = queue[msg.guild.id].slice(1) | |
} else { // if queue is empty or enabled looping | |
if (!loop[msg.guild.id].enabled && !loop[msg.guild.id].every) { // loop is disabled | |
msg.channel.send(lang.COMMAND_MUSIC_ENDED) | |
if (msg.guild.voice.connection && msg.guild.voice.connection.dispatcher) | |
msg.guild.voice.connection.dispatcher.removeListener('end', endHandler) | |
} else { // loop is enabled | |
if (loop[msg.guild.id].every) { | |
const seconds = parseInt(loop[msg.guild.id].every.replace(/\D{1,}/gm, '')) * 60 | |
setTimeout(() => { | |
play(connection, args[2], msg) | |
}, seconds * 1000) | |
} else { | |
await play(connection, args[2], msg) | |
} | |
} | |
} | |
} | |
msg.guild.voice.connection.dispatcher.on('end', endHandler) | |
}) | |
} else if (args[1] === 'volume') { | |
if (msg.guild.voice.connection && msg.guild.voice.connection.dispatcher && !msg.guild.voice.connection.dispatcher.destroyed) { | |
const before = msg.guild.voice.connection.dispatcher.volume | |
if (!isNumber(args[2])) return msg.channel.send(`:loud_sound: 現在の音量は${msg.guild.voice.connection.dispatcher.volume}です。`) | |
msg.guild.voice.connection.dispatcher.setVolume(parseInt(args[2]) / 100) | |
const emoji = before * 100 <= parseInt(args[2]) ? ':loud_sound:' : ':sound:' | |
msg.channel.send(f(emoji + lang.COMMAND_MUSIC_CHANGED_VOLUME, before * 100, parseInt(args[2]))) // oldvalue: 100 | |
} else return msg.channel.send(lang.COMMAND_MUSIC_NOT_PLAYING) | |
} else if (args[1] === 'skip') { | |
if (!loop[msg.guild.id].enabled && msg.guild.voice.connection && msg.guild.voice.connection.dispatcher && !msg.guild.voice.connection.dispatcher.destroyed) { | |
msg.guild.voice.connection.dispatcher.end() // Just stop the music and send end event, and play queue. | |
} else return msg.channel.send(lang.COMMAND_MUSIC_NOT_PLAYING + ' ...or enabled loop.') | |
} else if (args[1] === 'stop') { | |
queue[msg.guild.id] = [] | |
if (msg.guild.voice.connection && !msg.guild.voice.connection.dispatcher) { | |
msg.guild.voice.connection.dispatcher.destroy() // destroy. | |
if (msg.guild.me.voice && msg.guild.me.voice.channel && msg.guild.me.voice.channel.connection) msg.guild.me.voice.channel.connection.disconnect() | |
msg.channel.send(':wave:') | |
} else return msg.channel.send(lang.COMMAND_MUSIC_NOT_PLAYING) | |
} else if (args[1] === 'loop') { | |
Object.assign({[msg.guild.id]: []}, queue) | |
//queue.push({[msg.guild.id]: []}) | |
if (args[2] === 'disable') { | |
loop[msg.guild.id].every = null | |
loop[msg.guild.id].enabled = false | |
msg.channel.send(lang.COMMAND_MUSIC_DISABLED_LOOPING) | |
} else { | |
if (args[2] === 'every') { | |
if (args[3] === 'clear') return loop[msg.guild.id].every = null | |
if (!/\d{1,}m/gm.test(args[3])) return msg.channel.send(lang._invalid_args) | |
loop[msg.guild.id].enabled = true | |
loop[msg.guild.id].every = args[3] | |
msg.channel.send(f(lang.COMMAND_MUSIC_LOOP_EVERY, args[3])) | |
} else { | |
loop[msg.guild.id].enabled = loop[msg.guild.id].enabled ? false : true | |
msg.channel.send(f(lang.COMMAND_MUSIC_ONE_MUSIC_LOOP, loop[msg.guild.id].enabled ? lang.COMMAND_MUSIC_ENABLED : lang.COMMAND_MUSIC_DISABLED)) | |
} | |
} | |
} else if (args[1] === 'pause') { | |
if (msg.guild.voice.connection && msg.guild.voice.connection.dispatcher && !msg.guild.voice.connection.dispatcher.destroyed) { | |
msg.guild.voice.connection.dispatcher.pause() | |
msg.channel.send(lang.COMMAND_MUSIC_PAUSED) | |
} else msg.channel.send(lang.COMMAND_MUSIC_NOT_PLAYING) | |
} else if (args[1] === 'unpause' || args[1] === 'resume') { | |
if (msg.guild.voice.connection && msg.guild.voice.connection.dispatcher && !msg.guild.voice.connection.dispatcher.destroyed) { | |
msg.guild.voice.connection.dispatcher.resume() | |
msg.channel.send(lang.COMMAND_MUSIC_UNPAUSED) | |
} else msg.channel.send(lang.COMMAND_MUSIC_NOT_PLAYING) | |
} else if (args[1] === 'queue') { | |
msg.channel.send(f(lang.COMMAND_MUSIC_QUEUE_COUNT, queue.length)) | |
if (args[2] === 'clear') { | |
queue[msg.guild.id] = [] | |
return msg.channel.send(lang.COMMAND_MUSIC_CLEARED_QUEUE) | |
} else if (args[2] === 'reactivate') { | |
return msg.channel.send(f('```\n{0}music stop\n{0}music play https://www.youtube.com/watch?v=jhFDyDgMVUI\n```', prefix)) | |
} | |
const queues = queue[msg.guild.id] ? queue[msg.guild.id].map((e, i) => `${i}: ${e}`) : [] | |
if (queues.length) msg.channel.send(queues.join('\n')) | |
} else if (args[1] === 'status') { | |
if (msg.guild.voice.connection && msg.guild.voice.connection.dispatcher && !msg.guild.voice.connection.dispatcher.destroyed && playing[msg.guild.id]) msg.channel.send(f(lang.COMMAND_MUSIC_NOW_PLAYING, playing[msg.guild.id])) | |
else msg.channel.send(lang.COMMAND_MUSIC_NOT_PLAYING) | |
} else msg.channel.send(lang._invalid_args) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment