Pause resume loop

This commit is contained in:
Myx
2023-06-23 10:34:55 +02:00
committed by Azaaxin
parent d9408907dd
commit f09c13ac03
9 changed files with 197 additions and 59 deletions

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,8 +34,14 @@ 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);
}
});
});
// client.login(process.env.TOKEN);

View File

@@ -1,24 +1,42 @@
class MusicQueue {
constructor() {
this.queue = new Map();
constructor() {
this.queue = new Map();
this.looping = new Map();
}
addToQueue(guildId, song) {
if (!this.queue.has(guildId)) {
this.queue.set(guildId, []);
}
getQueue(guildId) {
if (!this.queue.has(guildId)) {
this.queue.set(guildId, []);
}
return this.queue.get(guildId);
this.queue.get(guildId).push(song);
}
removeFromQueue(guildId) {
if (!this.queue.has(guildId)) {
return;
}
addToQueue(guildId, song) {
const serverQueue = this.getQueue(guildId);
serverQueue.push(song);
}
const serverQueue = this.queue.get(guildId);
removeFromQueue(guildId) {
const serverQueue = this.getQueue(guildId);
if (this.looping.has(guildId) && this.looping.get(guildId)) {
serverQueue.push(serverQueue.shift());
} else {
serverQueue.shift();
}
}
module.exports = new MusicQueue();
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,7 +19,21 @@ 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)
)
];
const rest = new REST({ version: '9' }).setToken(token);