Creating functional loop, pause and unpause
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
const play = require('play-dl');
|
||||
|
||||
if (play.is_expired()) {
|
||||
async function ReAuth() {
|
||||
/*if (play.is_expired()) {
|
||||
await play.refreshToken()
|
||||
}
|
||||
}*/
|
||||
|
||||
play.getFreeClientID().then((clientID) => {
|
||||
play.setToken({
|
||||
@@ -15,4 +16,6 @@ play.getFreeClientID().then((clientID) => {
|
||||
})
|
||||
|
||||
play.authorization();
|
||||
}
|
||||
|
||||
module.exports.ReAuth = ReAuth;
|
||||
@@ -1,17 +1,32 @@
|
||||
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) {
|
||||
async function enableLooping(interaction) {
|
||||
await interaction.deferReply();
|
||||
const guildId = interaction.guild.id;
|
||||
musicQueue.enableLooping(guildId);
|
||||
interaction.followUp('Enabled looping for the current queue.');
|
||||
} else {
|
||||
}
|
||||
|
||||
async function unloopCommand(interaction) {
|
||||
await interaction.deferReply();
|
||||
const guildId = interaction.guild.id;
|
||||
musicQueue.disableLooping(guildId);
|
||||
interaction.followUp('Disabled looping for the current queue.');
|
||||
}
|
||||
|
||||
async function toggleLoopCommand(interaction) {
|
||||
await interaction.deferReply();
|
||||
const guildId = interaction.guild.id;
|
||||
if (musicQueue.looping.has(guildId) && musicQueue.looping.get(guildId)) {
|
||||
musicQueue.disableLooping(guildId, false);
|
||||
interaction.followUp('Disabled looping for the current queue.');
|
||||
} else {
|
||||
musicQueue.enableLooping(guildId, true);
|
||||
interaction.followUp('Enabled looping for the current queue.');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.loopCommand = loopCommand;
|
||||
module.exports.toggleLoopCommand = toggleLoopCommand;
|
||||
|
||||
module.exports.unloopCommand = unloopCommand;
|
||||
module.exports.enableLooping = enableLooping;
|
||||
24
commands/pause_resume.js
Normal file
24
commands/pause_resume.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const { getVoiceConnection } = require('@discordjs/voice');
|
||||
|
||||
async function pauseCommand(interaction) {
|
||||
await interaction.deferReply();
|
||||
const connection = getVoiceConnection(interaction.guild.id);
|
||||
if (!connection) {
|
||||
return interaction.followUp('There is no active music player in this server.');
|
||||
}
|
||||
connection.state.subscription.player.pause();
|
||||
interaction.followUp('Paused the music.');
|
||||
}
|
||||
|
||||
async function unpauseCommand(interaction) {
|
||||
await interaction.deferReply();
|
||||
const connection = getVoiceConnection(interaction.guild.id);
|
||||
if (!connection) {
|
||||
return interaction.followUp('There is no active music player in this server.');
|
||||
}
|
||||
connection.state.subscription.player.unpause();
|
||||
interaction.followUp('Unpaused the music.');
|
||||
}
|
||||
|
||||
module.exports.pauseCommand = pauseCommand;
|
||||
module.exports.unpauseCommand = unpauseCommand;
|
||||
@@ -27,9 +27,7 @@ async function playCommand(interaction) {
|
||||
selfMute: false
|
||||
});
|
||||
|
||||
musicPlayer(interaction.guild.id, connection);
|
||||
|
||||
interaction.followUp(`Added ${song.title} to the queue.`);
|
||||
musicPlayer(interaction.guild.id, connection, interaction);
|
||||
}
|
||||
|
||||
module.exports.playCommand = playCommand;
|
||||
16
index.js
16
index.js
@@ -2,9 +2,9 @@ const { Client, GatewayIntentBits } = require('discord.js');
|
||||
const { registerCommands } = require('./utils/registerCommands');
|
||||
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 { pauseCommand, unpauseCommand } = require('./commands/pause_resume');
|
||||
const { toggleLoopCommand } = require('./commands/loop');
|
||||
const { ReAuth } = require('./ReAuthenticate');
|
||||
|
||||
const process = require('dotenv').config();
|
||||
const clientId = process.parsed.clientId;
|
||||
@@ -37,12 +37,16 @@ client.on('interactionCreate', async (interaction) => {
|
||||
} else if (commandName === 'pause') {
|
||||
await pauseCommand(interaction);
|
||||
} else if (commandName === 'resume') {
|
||||
await resumeCommand(interaction);
|
||||
await unpauseCommand(interaction);
|
||||
} else if (commandName === 'loop') {
|
||||
await loopCommand(interaction);
|
||||
await toggleLoopCommand(interaction);
|
||||
}
|
||||
});
|
||||
|
||||
client.on('messageCreate', async (message) => {
|
||||
if(message.content == 'reauth') {
|
||||
await ReAuth();
|
||||
}
|
||||
});
|
||||
|
||||
// client.login(process.env.TOKEN);
|
||||
client.login(token);
|
||||
@@ -1,3 +1,5 @@
|
||||
const { getMusicStream } = require('./utils/getMusicStream');
|
||||
|
||||
class MusicQueue {
|
||||
constructor() {
|
||||
this.queue = new Map();
|
||||
@@ -12,7 +14,7 @@ class MusicQueue {
|
||||
this.queue.get(guildId).push(song);
|
||||
}
|
||||
|
||||
removeFromQueue(guildId) {
|
||||
async removeFromQueue(guildId) {
|
||||
if (!this.queue.has(guildId)) {
|
||||
return;
|
||||
}
|
||||
@@ -20,7 +22,9 @@ class MusicQueue {
|
||||
const serverQueue = this.queue.get(guildId);
|
||||
|
||||
if (this.looping.has(guildId) && this.looping.get(guildId)) {
|
||||
serverQueue.push(serverQueue.shift());
|
||||
const song = serverQueue.shift();
|
||||
const newSong = await getMusicStream(song.userInput);
|
||||
serverQueue.push(newSong);
|
||||
} else {
|
||||
serverQueue.shift();
|
||||
}
|
||||
@@ -34,8 +38,12 @@ class MusicQueue {
|
||||
return this.queue.get(guildId);
|
||||
}
|
||||
|
||||
setLooping(guildId, looping) {
|
||||
this.looping.set(guildId, looping);
|
||||
enableLooping(guildId) {
|
||||
this.looping.set(guildId, true);
|
||||
}
|
||||
|
||||
disableLooping(guildId) {
|
||||
this.looping.set(guildId, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ async function getStream(query) {
|
||||
return {
|
||||
title: songInformation.name,
|
||||
stream: stream.stream,
|
||||
duration: songInformation.durationInSec
|
||||
duration: songInformation.durationInSec / 1000,
|
||||
userInput: query
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,33 +6,33 @@ async function getStream(query) {
|
||||
const regex = /(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))([^?&\n]+)/;
|
||||
const match = query.match(regex);
|
||||
let videoId;
|
||||
|
||||
let usingYtsr = false;
|
||||
if(match == null) {
|
||||
const searchResults = await ytsr(query, { page: 1, type: 'video' });
|
||||
videoId = searchResults.items[0].id;
|
||||
// videoId = null;
|
||||
|
||||
console.log(searchResults.items[0].id)
|
||||
let result = await playdl.search(query, { limit: 1});
|
||||
videoId = result[0].id;
|
||||
|
||||
if (videoId == null) {
|
||||
let result = await playdl.search(query, { limit: 1})
|
||||
let videoUrl = result[0].url;
|
||||
videoId = videoUrl.match(regex)[1];
|
||||
usingYtsr = true;
|
||||
const searchResults = await ytsr(query, { page: 1, type: 'video' });
|
||||
videoId = searchResults.items[0].id;
|
||||
}
|
||||
} else {
|
||||
videoId = match[1];
|
||||
}
|
||||
|
||||
const streamResult = await playdl.stream(`https://www.youtube.com/watch?v=${videoId}`, { quality: 2 });
|
||||
const infoResult = await ytsr(`https://www.youtube.com/watch?v=${videoId}`, { limit: 1});
|
||||
|
||||
const infoResult = usingYtsr ? await ytsr(`https://www.youtube.com/watch?v=${videoId}`, { limit: 1}) : await playdl.video_info(`https://www.youtube.com/watch?v=${videoId}`);
|
||||
console.log(infoResult)
|
||||
console.log("\x1b[36m",' Id: ', videoId, 'Alternative search:', usingYtsr)
|
||||
return {
|
||||
title: infoResult.items[0].title ?? 'Unknown',
|
||||
duration: infoResult.items[0].duration ?? 0,
|
||||
title: (usingYtsr ? infoResult.items[0].title : infoResult.video_details.title) ?? 'Unknown, error fetching title.',
|
||||
duration: (usingYtsr ? infoResult.items[0].duration : infoResult.video_details.durationInSec) ?? 'Unknown, error fetching duration.',
|
||||
stream: streamResult.stream,
|
||||
type: streamResult.type
|
||||
type: streamResult.type,
|
||||
userInput: query
|
||||
};
|
||||
} catch (error) {
|
||||
console.log("\x1b[31m", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"description": "Discord music bot",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,11 +26,8 @@
|
||||
"discord.js": "^14.11.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"ffmpeg-static": "^4.2.7",
|
||||
"libsodium-wrappers": "^0.7.11",
|
||||
"opusscript": "^0.1.0",
|
||||
"play-dl": "^1.9.6",
|
||||
"sodium": "^3.0.2",
|
||||
"sodium-native": "^4.0.4",
|
||||
"soundcloud-scraper": "^5.0.3",
|
||||
"spotify-web-api-node": "^5.0.2",
|
||||
"tweetnacl": "^1.0.3",
|
||||
|
||||
@@ -9,6 +9,7 @@ async function getMusicStream(query) {
|
||||
let songTitle;
|
||||
let songDuration;
|
||||
let type = StreamType.Opus;
|
||||
let userInput = query;
|
||||
|
||||
if (query.includes('spotify.com')) {
|
||||
stream = await spotify.getStream(query);
|
||||
@@ -34,6 +35,7 @@ async function getMusicStream(query) {
|
||||
return {
|
||||
title: songTitle,
|
||||
duration: songDuration,
|
||||
userInput: userInput,
|
||||
stream: stream,
|
||||
type: type
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ const {
|
||||
} = require('@discordjs/voice');
|
||||
const musicQueue = require('../musicQueue');
|
||||
|
||||
async function musicPlayer(guildId, connection) {
|
||||
async function musicPlayer(guildId, connection, interaction) {
|
||||
const serverQueue = musicQueue.getQueue(guildId);
|
||||
|
||||
if (serverQueue.length === 0) {
|
||||
@@ -31,37 +31,21 @@ async function musicPlayer(guildId, connection) {
|
||||
noSubscriber: NoSubscriberBehavior.Play
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
player.play(resource)
|
||||
|
||||
connection.subscribe(player)
|
||||
|
||||
player.on(AudioPlayerStatus.Idle, () => {
|
||||
interaction.followUp(`Added **${song.title}** to the queue.`).then(message =>
|
||||
setTimeout(() =>
|
||||
message.delete(),
|
||||
song.duration + 10000));
|
||||
|
||||
player.on(AudioPlayerStatus.Idle, async () => {
|
||||
console.log('Song ended:', song.title);
|
||||
musicQueue.removeFromQueue(guildId);
|
||||
musicPlayer(guildId, connection);
|
||||
await musicQueue.removeFromQueue(guildId)
|
||||
});
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
// TODO: USE THIS AGAIN
|
||||
function convertToMilliseconds(songLenth) {
|
||||
try {
|
||||
let time = songLenth.split(':')
|
||||
let milliseconds = 0;
|
||||
if(time.length == 3) {
|
||||
milliseconds = (parseInt(time[0]) * 60 * 60 * 1000) + (parseInt(time[1]) * 60 * 1000) + (parseInt(time[2]) * 1000)
|
||||
} else if(time.length == 2) {
|
||||
milliseconds = (parseInt(time[0]) * 60 * 1000) + (parseInt(time[1]) * 1000)
|
||||
} else if(time.length == 1) {
|
||||
milliseconds = (parseInt(time[0]) * 1000)
|
||||
}
|
||||
return milliseconds
|
||||
} catch (error) {
|
||||
return 10000;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.musicPlayer = musicPlayer;
|
||||
@@ -28,12 +28,7 @@ async function registerCommands(clientId, token) {
|
||||
.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)
|
||||
)
|
||||
.setDescription('Loops the current song! (toggle)'),
|
||||
];
|
||||
|
||||
const rest = new REST({ version: '9' }).setToken(token);
|
||||
|
||||
Reference in New Issue
Block a user