const mpv = require('node-mpv'); const prism = require('prism-media'); const { Client, Intents, VoiceChannel} = require('discord.js'); const { joinVoiceChannel, createAudioPlayer, createAudioResource, entersState, NoSubscriberBehavior, StreamType, AudioPlayerStatus, VoiceConnectionStatus, } = require('@discordjs/voice'); const delay = ms => new Promise(res => setTimeout(res, ms)); global.client = new Client({ intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES ], disableMentions: 'everyone', }); client.music = {title:undefined, duration: undefined, pos:-1, count:0, report:false}; client.on("ready", () => { console.log(`${client.user.username} ready!`); client.user.setActivity(`H C L`, { type: 'WATCHING' }); }); client.on("warn", (info) => console.log(info)); client.on("error", console.error); client.login(process.env.DISCORD_BOT_TOKEN); client.exec={}; client.exec.format_url= function (url) { return url.includes("://") ? url : 'ytdl://ytsearch:"'+url+'"'}; const mpvPlayer = new mpv({audio_only:true, "verbose": false,},['--audio-device=pulse/MPVSink', '--ytdl-format=bestaudio']);//, '--demuxer-readahead-secs=2',' --demuxer-max-bytes=500M']); var channel = null; mpvPlayer.start().then(e=>console.log("MPV Started")).catch(e=>console.error(e)); mpvPlayer.on('status', (status) => { console.log(status); if(status.property=='media-title'){ if(client.music.duration) client.music.title = status.value; } if(status.property=='duration'){ client.music.duration = status.value; } if(status.property=='playlist-count'){ client.music.count = status.value; client.music.report = false; }else if(status.property=='playlist-pos'){ client.music.pos = status.value; client.music.report = false }else if(client.music.title && client.music.duration){ client.channels.fetch(channel).then(c=>{ if(client.music.title && client.music.duration && client.music.report==false){ c.send('Playing: '+client.music.title+" ("+Math.floor(client.music.duration/60)+":"+Math.floor(client.music.duration%60)+")"); client.music.report = true; } }); } }); mpvPlayer.on('stopped', (e) => { console.log(e) if(channel && client.music.pos == -1) client.channels.fetch(channel).then(c=>c.send('Finished playing... Gime more music UwU')); }); const player = createAudioPlayer({ behaviors: { noSubscriber: NoSubscriberBehavior.Play, maxMissedFrames: 250, }, }); const resource = createAudioResource(new prism.FFmpeg({ args: ['-analyzeduration','0','-loglevel','0', '-f', 'pulse','-i', 'MPVSink.monitor', '-acodec','libopus','-f','opus', '-ar','48000','-ac','2', ], }), {inputType: StreamType.OggOpus}); player.play(resource); client.exec.play = async(message, url)=>{ if(channel == null){ const vchannel = message.member.voice.channel; if (!vchannel) return message.reply("You are not currently in a voice channel"); const permissions = vchannel.permissionsFor(message.client.user); if (!permissions.has("CONNECT")) return message.reply("I am not allowed to join voice T_T"); if (!permissions.has("SPEAK")) return message.reply("I am not allowed to speak T_T"); const vc = joinVoiceChannel({ channelId: message.member.voice.channel.id, guildId: message.guild.id, adapterCreator: message.guild.voiceAdapterCreator }) vc.subscribe(player); channel = message.channelId; } mpvPlayer.load(client.exec.format_url(url),'replace').catch(e=>{}); return entersState(player, AudioPlayerStatus.Playing, 10e5); } client.exec.stop = (message)=>{ mpvPlayer.stop().catch(e=>{}); message.guild.me.voice.disconnect("Ended Playback"); channel = null; } client.exec.queue = (message)=>{ let url = message.content.slice(6); if(channel){ mpvPlayer.load(client.exec.format_url(url),'append-play').catch(e=>{}); }else{ client.exec.play(message,url); } } client.exec.skip = (message)=>{ if(channel) mpvPlayer.next().catch(e=>{}); } client.on("message", async (message) => { if (message.author.bot) return; if (!message.guild) return; if (message.content.indexOf("stop")==0){ client.exec.stop(message); }else if (message.content.indexOf("play")==0){ client.exec.play(message, message.content.slice(5)); }else if (message.content.indexOf("queue")==0){ client.exec.queue(message); }else if (message.content.indexOf("skip")==0){ client.exec.skip(message); } });