const {createAudioPlayer, createAudioResource, joinVoiceChannel, getVoiceConnection} = require("@discordjs/voice") const { Message } = require("discord.js") const {client, dir} = require("../index") const YTDlpWrap = require("yt-dlp-wrap").default const ytDlp = new YTDlpWrap(`${dir}/yt-dlp`) const players = {} module.exports.commands = [ { name: "play", description: "Joins your VC and plays music by youtube link.", arguments: ["link"], // If its not a OBJECT type you provide it like that lol. run: async (ctx, link) => { // Getting the guild member to get their voice client const author = ctx.author const member = await ctx.guild.members.fetch(author) // Initiating the channel variable (undefined) var channel // Checking if member is in a voice chat if (member.voice) { channel = member.voice.channel } // Returns if the user is not in vc or the bot is already in one if (!channel) { return ctx.reply("You are not in a VC right now.") } else if (ctx.guild.members.me.voice.channel && ctx.guild.members.me.voice.channel.id != channel.id) { return ctx.reply("Already in a vc.") } var connection // Checking if the bot is already in the vc if (!ctx.guild.members.me.voice.channel) { // Connecting to voice channel connection = joinVoiceChannel({ channelId: channel.id, guildId: channel.guild.id, adapterCreator: channel.guild.voiceAdapterCreator, }) } else { // Getting a existing connection connection = getVoiceConnection(ctx.guild.id) } const reply = await ctx.reply("Loading music data.") // Running yt-dlp (getting music title) const metadata = await ytDlp.getVideoInfo(link); await reply.edit(`Downloading ${metadata.title}`) // Running yt-dlp (downloading music) const music = ytDlp.exec([ // Arguments to run yt-dlp with link, '-f', 'best', '-o', `${dir}/music/${metadata.title}.mp3`, '--extract-audio', '--audio-format', 'mp3' ]).on('close', () => { reply.edit(`Playing ${metadata.title}`) // Stopping old audioplayer if (players[ctx.guild.id]) { players[ctx.guild.id].stop() } if (!ctx.guild.members.me.voice || (ctx.guild.members.me.voice && !ctx.guild.members.me.voice.channel) || (ctx.guild.members.me.voice && ctx.guild.members.me.voice.channel && ctx.guild.members.me.voice.channel.id != channel.id)) { return reply.edit("Not in a VC anymore, not playing.") } // Connecting audio player const player = createAudioPlayer() players[ctx.guild.id] = player // Loading music const resource = createAudioResource(`${dir}/music/${metadata.title}.mp3`) // Playing the music with the player player.play(resource) // Subscribing the connection to the player connection.subscribe(player) }) } }, { name: "stop", description: "Stop music", run: (ctx) => { const voice = ctx.guild.members.me.voice if (!voice || !players[ctx.guild.id]) { return ctx.reply("Not in a voice channel.") } players[ctx.guild.id].stop() } }, { name: "leave", description: "Leave the channel", run: (ctx) => { const voice = ctx.guild.members.me.voice if (!voice || !players[ctx.guild.id]) { return ctx.reply("Not in a voice channel.") } players[ctx.guild.id].stop() voice.disconnect() } } ] module.exports.players = players // For use in events/voice.js