I'm new to the coding scene and i have created a music Bot with Discord.js V13 but I keep getting an error that stops the music while playing. I don't know how to fix it and I didn't find any solutions.
Here's the code:
const { Client, VoiceChannel } = require('discord.js');
const config = require('./config.json');
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const {
NoSubscriberBehavior,
createAudioPlayer,
createAudioResource,
entersState,
VoiceConnectionStatus,
joinVoiceChannel,
AudioPlayerStatus,
} = require('@discordjs/voice');
const voice = require('@discordjs/voice');
const prefix = '?';
const queue = new Map();
//------------------------------------------------Important----------------------------------------------------------
const player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Pause,
},
});
async function connectToChannel(channel) {
const connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator,
});
try {
await entersState(connection, VoiceConnectionStatus.Ready, 30_000);
return connection;
} catch (error) {
connection.destroy();
throw error;
}
}
const client = new Client({ intents: ['GUILDS', 'GUILD_MESSAGES', 'GUILD_VOICE_STATES'] });
client.on('ready', async () => {
console.log('Bot is on!');
//attachRecorder();
});
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
}
const validURL = (str) =>{
var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
if(!regex.test(str)){
return false;
} else {
return true;
}
}
client.on('messageCreate', async (message) => {
if (!message.guild) return;
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
const channel = message.member?.voice.channel;
const serverQueue = queue.get(message.guild.id);
if(channel){
if(command === 'play'){
execute(message, serverQueue, args);
return;
} else if (command === 'skip') {
skip(serverQueue);
return;
} else if (command === 'stop') {
stop(serverQueue);
return;
}else if(command === 'leave'){
leave(serverQueue);
return;
}else if(command === 'pause'){
pause(serverQueue);
return;
}else if(command === 'resume'){
resume(serverQueue);
return;
}
}else {
message.channel.send('Du bist in keinem Kanal!');
}
});
//------------------------------------------------Important----------------------------------------------------------
//------------------------------------------------Befehle------------------------------------------------------------
async function execute(message, serverQueue, args) {
const voiceChannel = message.member?.voice.channel;
if (!voiceChannel)
return message.channel.send("Du must in einem Sprachkanal sein!");
/*const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
return message.channel.send(
"I need the permissions to join and speak in your voice channel!"
);
}*/
var video;
if (args[0] === '') {
message.channel.send("Es ist kein Link/Video-Name eingegeben worden.");
} else {
video = await videoFinder(args.join(' '));
}
var url;
if(validURL(args[0])){
try{
url = args[0];
} catch(err){
console.log(err);
return message.channel.send(err);
}
} else if(video){
url = video.url;
} else {
message.channel.send('Kein Video gefunden!');
}
const songinfo = await ytdl.getInfo(url);
const song = {
title: songinfo.videoDetails.title,
url: songinfo.videoDetails.video_url,
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songStream: null,
songs: [],
volume: 5,
playing: true
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
const connection = await connectToChannel(voiceChannel);
queueContruct.connection = connection;
connection.subscribe(player);
play(message.guild, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
return message.channel.send(`**${song.title}** wurde zur Warteschlange hinzugefügt.`);
//
}
}
function leave(serverQueue){
player.stop();
serverQueue.songs = [];
serverQueue.connection.destroy();
}
function pause(serverQueue){
if (!serverQueue)
return serverQueue.textChannel.send("Es gibt kein Lied zum Pausen!");
player.pause();
}
function resume(serverQueue){
if (!serverQueue)
return serverQueue.textChannel.send("Es gibt kein Lied zum Entpausen!");
player.unpause();
}
function skip(serverQueue) {
if (!serverQueue)
return serverQueue.textChannel.send("Es gibt kein Lied zum Skippen!");
player.stop();
}
function stop(serverQueue) {
if (!serverQueue)
return serverQueue.textChannel.send("Es gibt kein Lied zum Stoppen!");
serverQueue.songs = [];
player.stop();
}
function volume(serverQueue) {
if (!serverQueue)
return serverQueue.textChannel.send("Es gibt kein Lied zum wo die Lautstärke geändert werden kann!");
serverQueue.vol
}
//------------------------------------------------Befehle------------------------------------------------------------
//------------------------------------------------Crab---------------------------------------------------------------
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.connection.disconnect();
queue.delete(guild.id);
return;
}
var songStream;
try {
const buffer = ytdl(song.url, { filter: "audioonly" });
songStream = createAudioResource(buffer, { inlineVolume: true }, {
'options': '-vn',
"before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5"
});
} catch (error) {
console.log(error);
}
player.play(songStream);
player.on(AudioPlayerStatus.Idle, () => {
serverQueue.songs.shift();
play(guild, serverQueue.songs[0])
});
player.on("error", error => console.error(error));
songStream.volume.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.songStream = songStream;
serverQueue.textChannel.send(`Spielt jetzt: **${song.title}**`);
}
//------------------------------------------------Crab---------------------------------------------------------------
void client.login(config.token);
and when the music stops i get this error but the bot sill runs :
N [Error]: aborted
at connResetException (node:internal/errors:691:14)
at TLSSocket.socketCloseListener (node:_http_client:407:19)
at TLSSocket.emit (node:events:402:35)
at node:net:687:12
at TCP.done (node:_tls_wrap:580:7) {
resource: j {
playStream: Encoder {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
encoder: null,
_options: [Object],
_required: 3840,
_buffer: null,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: [Function: bound onwrite]
},
edges: [ [Object], [Object], [Object] ],
metadata: null,
volume: VolumeTransformer {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
_readInt: [Function (anonymous)],
_writeInt: [Function (anonymous)],
_bits: 16,
_bytes: 2,
_extremum: 32768,
volume: 1,
_chunk: null,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: [Function: bound onwrite]
},
encoder: Encoder {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
encoder: null,
_options: [Object],
_required: 3840,
_buffer: null,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: [Function: bound onwrite]
},
audioPlayer: H {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_state: [Object],
subscribers: [Array],
behaviors: [Object],
debug: [Function (anonymous)],
[Symbol(kCapture)]: false
},
playbackDuration: 56800,
started: true,
silencePaddingFrames: 5,
silenceRemaining: -1
}
}
How do I fix this?
I have encountered that same issue, so I looked around and eventually found this gem.
This is extracted from discordjs' own implementation of a music bot. Here they override the
createAudioResource
function with an executable wrapper for ytdl, and you will need to do the same. The npm package required here isyoutube-dl-exec
.Audio worked perfectly for me from there, and this seemed to be the only way to fix it as well.