Pause resume loop

This commit is contained in:
Myx
2023-06-23 10:34:55 +02:00
parent d9408907dd
commit 8c08c088f1
10 changed files with 199 additions and 59 deletions

2
.env Normal file
View File

@@ -0,0 +1,2 @@
token="MTExOTYyOTQwNzk5NzQwNzMwMg.GOuub1.r8FZ_DWaouO17vO2QpgcDI-zTh4iTuUrgNZRbY"
clientId="1119629407997407302"

17
commands/loop.js Normal file
View File

@@ -0,0 +1,17 @@
const musicQueue = require('../musicQueue');
async function loopCommand(interaction) {
await interaction.deferReply();
const looping = interaction.options.getBoolean('looping');
musicQueue.setLooping(interaction.guild.id, looping);
if (looping) {
interaction.followUp('Enabled looping for the current queue.');
} else {
interaction.followUp('Disabled looping for the current queue.');
}
}
module.exports.loopCommand = loopCommand;

32
commands/pause.js Normal file
View File

@@ -0,0 +1,32 @@
const { musicPlayer } = require('../utils/musicPlayer');
const { AudioPlayerStatus, joinVoiceChannel, AudioPlayerState } = require('@discordjs/voice');
async function pauseCommand(interaction) {
await interaction.deferReply();
const voiceChannel = interaction.member.voice.channel;
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false
});
let player = await musicPlayer(interaction.guild.id, connection, false);
if (!voiceChannel) {
return interaction.followUp('You must be in a voice channel to use this command.');
}
if (!player) {
return interaction.followUp('I am not currently playing music in a voice channel.');
}
// player.pause();
interaction.followUp('Paused the music.');
}
module.exports.pauseCommand = pauseCommand;

35
commands/play.js Normal file
View File

@@ -0,0 +1,35 @@
const { getMusicStream } = require('./../utils/getMusicStream');
const musicQueue = require('../musicQueue');
const { musicPlayer } = require('../utils/musicPlayer');
const {
joinVoiceChannel,
} = require('@discordjs/voice');
async function playCommand(interaction) {
await interaction.deferReply();
const query = interaction.options.getString('input');
const voiceChannel = interaction.member.voice.channel;
if (!voiceChannel) {
return interaction.followUp('You must be in a voice channel to use this command.');
}
const song = await getMusicStream(query);
musicQueue.addToQueue(interaction.guild.id, song);
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false
});
musicPlayer(interaction.guild.id, connection);
interaction.followUp(`Added ${song.title} to the queue.`);
}
module.exports.playCommand = playCommand;

32
commands/resume.js Normal file
View File

@@ -0,0 +1,32 @@
const { musicPlayer } = require('../utils/musicPlayer');
const { joinVoiceChannel } = require('@discordjs/voice');
async function resumeCommand(interaction) {
await interaction.deferReply();
const voiceChannel = interaction.member.voice.channel;
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false
});
let player = await musicPlayer(interaction.guild.id, connection, false);
if (!voiceChannel) {
return interaction.followUp('You must be in a voice channel to use this command.');
}
if (!player) {
return interaction.followUp('I am not currently playing music in a voice channel.');
}
player.unpause();
interaction.followUp('Resumed the music.');
}
module.exports.resumeCommand = resumeCommand;

View File

@@ -1,9 +1,12 @@
const { playCommand } = require('./play.js');
const { Client, GatewayIntentBits } = require('discord.js');
const { queueCommand } = require('./commands/queue');
const { registerCommands } = require('./utils/registerCommands');
const process = require('dotenv').config();
const { playCommand } = require('./commands/play');
const { queueCommand } = require('./commands/queue');
const { pauseCommand } = require('./commands/pause');
const { resumeCommand } = require('./commands/resume');
const { loopCommand } = require('./commands/loop');
const process = require('dotenv').config();
const clientId = process.parsed.clientId;
const token = process.parsed.token;
@@ -31,6 +34,12 @@ client.on('interactionCreate', async (interaction) => {
await playCommand(interaction);
} else if (commandName === 'queue') {
await queueCommand(interaction);
} else if (commandName === 'pause') {
await pauseCommand(interaction);
} else if (commandName === 'resume') {
await resumeCommand(interaction);
} else if (commandName === 'loop') {
await loopCommand(interaction);
}
});

View File

@@ -1,24 +1,42 @@
class MusicQueue {
constructor() {
this.queue = new Map();
}
getQueue(guildId) {
if (!this.queue.has(guildId)) {
this.queue.set(guildId, []);
}
return this.queue.get(guildId);
this.looping = new Map();
}
addToQueue(guildId, song) {
const serverQueue = this.getQueue(guildId);
serverQueue.push(song);
if (!this.queue.has(guildId)) {
this.queue.set(guildId, []);
}
this.queue.get(guildId).push(song);
}
removeFromQueue(guildId) {
const serverQueue = this.getQueue(guildId);
if (!this.queue.has(guildId)) {
return;
}
const serverQueue = this.queue.get(guildId);
if (this.looping.has(guildId) && this.looping.get(guildId)) {
serverQueue.push(serverQueue.shift());
} else {
serverQueue.shift();
}
}
getQueue(guildId) {
if (!this.queue.has(guildId)) {
return [];
}
return this.queue.get(guildId);
}
setLooping(guildId, looping) {
this.looping.set(guildId, looping);
}
}
module.exports = new MusicQueue();

View File

@@ -24,10 +24,10 @@ async function getMusicStream(query) {
type = StreamType.OggOpus;
} else {
stream = await youtube.getStream(query);
songTitle = stream.title ?? 'Unknown';
songDuration = stream.duration ?? 'Unknown';
stream = stream.stream;
stream = await youtube.getStream(query)
songTitle = stream?.title ?? 'Unknown';
songDuration = stream?.duration ?? 'Unknown';
stream = stream?.stream;
type = StreamType.Opus;
}

View File

@@ -1,40 +1,12 @@
const {
joinVoiceChannel,
createAudioResource,
createAudioPlayer,
NoSubscriberBehavior,
AudioPlayerStatus,
} = require('@discordjs/voice');
const musicQueue = require('./musicQueue');
const { getMusicStream } = require('./utils/getMusicStream');
const musicQueue = require('../musicQueue');
async function playCommand(interaction) {
await interaction.deferReply();
const query = interaction.options.getString('input');
const voiceChannel = interaction.member.voice.channel;
if (!voiceChannel) {
return interaction.followUp('You must be in a voice channel to use this command.');
}
const song = await getMusicStream(query);
musicQueue.addToQueue(interaction.guild.id, song);
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false
});
playSong(interaction.guild.id, connection);
interaction.followUp(`Added ${song.title} to the queue.`);
}
async function playSong(guildId, connection) {
async function musicPlayer(guildId, connection) {
const serverQueue = musicQueue.getQueue(guildId);
if (serverQueue.length === 0) {
@@ -44,6 +16,12 @@ async function playCommand(interaction) {
const song = serverQueue[0];
if(song.stream == null){
musicQueue.removeFromQueue(guildId);
musicPlayer(guildId, connection);
return;
}
let resource = createAudioResource(song.stream, {
inputType: song.type
})
@@ -54,6 +32,7 @@ async function playCommand(interaction) {
}
})
player.play(resource)
connection.subscribe(player)
@@ -61,8 +40,10 @@ async function playCommand(interaction) {
player.on(AudioPlayerStatus.Idle, () => {
console.log('Song ended:', song.title);
musicQueue.removeFromQueue(guildId);
playSong(guildId, connection);
musicPlayer(guildId, connection);
});
return player;
}
// TODO: USE THIS AGAIN
@@ -83,4 +64,4 @@ function convertToMilliseconds(songLenth) {
}
}
module.exports.playCommand = playCommand;
module.exports.musicPlayer = musicPlayer;

View File

@@ -19,6 +19,20 @@ async function registerCommands(clientId, token) {
option.setName('song')
.setDescription('Add song from YouTube, Spotify, SoundCloud, etc. to the queue')
.setRequired(true)
),
new SlashCommandBuilder()
.setName('pause')
.setDescription('Pauses the current song!'),
new SlashCommandBuilder()
.setName('resume')
.setDescription('Resumes the current song!'),
new SlashCommandBuilder()
.setName('loop')
.setDescription('Loops the current song!')
.addBooleanOption(option =>
option.setName('looping')
.setDescription('Enable or disable looping')
.setRequired(true)
)
];