Discord.js YTDL-核心崩溃
Discord.js YTDL-Core Crashing
我用 Node.js 和 YTDl-Core 为 Discord 写了一个音乐机器人。我可以播放 YouTube 上的每一首歌曲,但有一个限制,如果我播放一个 song/video 的频道,它很少将其添加到队列中,但无法播放并且机器人离开了 VoiceChannel,但我没有'得到一个错误,如果我尝试使用它完全工作的机器人,那么只要我坚持这个限制。这是我的代码:
const Discord = require('discord.js')
const fs = require('fs')
const ytdl = require('ytdl-core')
const ffmpeg = require('ffmpeg')
const { debug, Console } = require('console')
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
const ytapi3 = config.GoogleApiYT3
const search = require('youtube-search')
const { getInfo } = require('ytdl-core')
const queue = new Map()
var client = new Discord.Client()
//setting status
client.on('ready', () => {
console.log("Logged in as", client.user.username, "...")
client.user.setPresence({
status: config.status,
activity: {
name: config.activity,
type: 'STREAMING',
url: config.streamingURL
}
})
})
//musicbot
client.on('message', async message => {
if(message.author.bot) return // test if bot has written this message
if(!message.channel.id == config.botcommandsChannelID) return //test if message is in botcommands channel
if(!message.content.startsWith(config.prefix)) return // test if prefix is used
const args = message.content.substring(config.prefix.length).split(" ") // split arguments into args[]-list and cut the prefix out
const voiceChannel = message.member.voice.channel
const serverqueue = queue.get(message.guild.id)
//test if user has permissions to use command
if(config.UseDJRole == "true") {
if(message.member.roles.cache.has(config.DJroleID) || message.member.roles.cache.has(config.ModeratorRoleID) || message.member.user.id == config.owner){
}else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToUseThisCommand)
}
}
if(!voiceChannel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_404) //testing if user is in voiceChannel
if(message.content.startsWith(config.prefix + config.PlayCommand)){ //Play-case
const permission = voiceChannel.permissionsFor(message.client.user)
if(!permission.has('CONNECT')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToJoinVC)
if(!permission.has('SPEAK')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToSpeakInVC)
var song = {
url: null,
title: null
}
//get link "song"
if(args.length >= 2){
if(ytdl.validateURL(args[1])){
args.shift()
try{
song = await searchOnYT(args[0], message.channel);
}catch(error){
return console.log("returned")
}
} else{
args.shift()
const vidSearchLink = args.join(' ')
try{
song = await searchOnYT(vidSearchLink, message.channel);
} catch(error){
return console.log("returned")
}
}
}else {
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoArgs)
}
if(!serverqueue){
const queueConstruct = {
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: config.musicDefaultVolume,
playing: true
}
queue.set(message.guild.id, queueConstruct)
queueConstruct.songs.push(song)
try {
queueConstruct.connection = await voiceChannel.join()
play(message.guild, queueConstruct.songs[0], message)
} catch (error) {
console.log(error)
queue.delete(message.guild.id)
return sendEmbed(message.channel, config.ErrorColor, "Error", config.ErrorDuringConnectingToVoiceChannel)
}
}else{
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id){
return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)
} else{
try {
_url = song.url
//add to queue
serverqueue.songs.push(song)
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Adding", song.title + config.addedToQueue, _url)
} catch (error) {
console.log(error)
return sendEmbed(message.channel, config.ErrorColor, "Error", config.ErrorDuringAddingToQueue)
}
}
}
return undefined
}else if(message.content.startsWith(config.prefix + config.StopCommand) || message.content.startsWith(config.prefix + config.LeaveCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
serverqueue.songs = []
serverqueue.connection.dispatcher.end()
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Stopping", config.stoped)
}else if(message.content.startsWith(config.prefix + config.PauseCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
if(!serverqueue.playing) return sendEmbed(message.channel, config.ErrorColor, "Error", config.AllredyPaused)
serverqueue.playing = false
serverqueue.connection.dispatcher.pause()
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Pausing", config.Paused)
}else if(message.content.startsWith(config.prefix + config.ResumeCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
if(serverqueue.playing) return sendEmbed(message.channel, config.ErrorColor, "Error", config.AllredyPlaying)
serverqueue.playing = true
serverqueue.connection.dispatcher.resume()
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Resuming", config.Resumed)
}else if(message.content.startsWith(config.prefix + config.SkipCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
serverqueue.connection.dispatcher.end()
return console.log("skipped")
}else if(message.content.startsWith(config.prefix + config.QueueCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)//test if you are in one voice channel with the bot
if(serverqueue){
if(serverqueue.playing){
var status = config.Resumed
}else{
var status = config.Paused
}
const embedMessage = new Discord.MessageEmbed()
.setColor(config.MusicEmbedColorHEX)
.setTitle("Queue | volume(" + serverqueue.volume + "/5)" + status)
for (let index = 0; index < serverqueue.songs.length; index++) {
embedMessage.addField(serverqueue.songs[index].title, serverqueue.songs[index].url)
}
return message.channel.send(embedMessage)
} else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue)
}
}else if(message.content.startsWith(config.prefix + config.VolumeCommand) || message.content.startsWith(config.prefix + config.VCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)//test if you are in one voice channel with the bot
if(!args[1]){
if(serverqueue.volume == 0){
var v = config.VMute
}else{
var v = config.VUnMute
for (let index = 0; index < serverqueue.volume; index++) {
v = v + config.VSymbol
}
}
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Volume (" + serverqueue.volume + "/5)", v) //return volume
}
if(args[1] == "+" || args[1] == "plus"){
if(serverqueue.volume == 5) return sendEmbed(message.channel, config.ErrorColor, "Error", config.MaxVolume)
serverqueue.volume = serverqueue.volume + 1
if(serverqueue.volume == 0){
var v = config.VMute
}else{
var v = config.VUnMute
for (let index = 0; index < serverqueue.volume; index++) {
v = v + config.VSymbol
}
}
serverqueue.connection.dispatcher.setVolumeLogarithmic(serverqueue.volume / 5)
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Volume (" + serverqueue.volume + "/5)", v) //return volume
}else if(args[1] == "-" || args[1] == "minus"){
if(serverqueue.volume == 0) return sendEmbed(message.channel, config.ErrorColor, "Error", config.MinVolume)
serverqueue.volume = serverqueue.volume - 1
if(serverqueue.volume == 0){
var v = config.VMute
}else{
var v = config.VUnMute
for (let index = 0; index < serverqueue.volume; index++) {
v = v + config.VSymbol
}
}
serverqueue.connection.dispatcher.setVolumeLogarithmic(serverqueue.volume / 5)
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Volume (" + serverqueue.volume + "/5)", v) //return volume
}else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.VSyntax) //return volume
}
}
})
function sendEmbed(_channel, _Color, _Title, _Description, _URL){
const embedMessage = new Discord.MessageEmbed()
.setColor(_Color)
.setTitle(_Title)
.setDescription(_Description)
.setURL(_URL);
_channel.send(embedMessage)
}
function searchOnYT(searchstring, _channel){
var opts = {
maxResults: 1,
key: config.GoogleApiYT3,
type: 'video'
}
return new Promise((resolve, reject) => {
search(searchstring, opts, function(err, results) {
if(err) reject(err);
if(results) {
const r = results[0]
u = r.link
t = r.title.replaceAll(""", '"').replaceAll("&", "&")
var ar = {
url: u,
title: t
}
resolve(ar)
}
else {
sendEmbed(_channel, config.ErrorColor, "Error", config.NoResultsFound+ searchstring);
var e = new Error(["no videofound"])
reject(e)
}
})
});
}
function play(guild, song, message){
const serverqueue = queue.get(guild.id)
if(!song){
serverqueue.voiceChannel.leave()
queue.delete(guild.id)
client.user.setPresence({
status: config.status,
activity: {
name: config.activity,
type: 'STREAMING',
url: config.streamingURL
}
})
return (message.channel, config.MusicEmbedColorHEX, "Stopping", config.PlayedQueueTrough)
}
client.user.setPresence({
status: config.status,
activity: {
name: "Music",
type: 'STREAMING',
url: serverqueue.songs[0].url
}
})
const dispatcher = serverqueue.connection.play(ytdl(song.url))
.on('finish', () => {
serverqueue.songs.shift()
play(guild, serverqueue.songs[0], message)
})
.on('error', error => {
console.log(error)
})
dispatcher.setVolumeLogarithmic(serverqueue.volume / 5)
sendEmbed(message.channel, config.MusicEmbedColorHEX, "Playing", config.startPlaying + serverqueue.songs[0].title, serverqueue.songs[0].url)
}
client.login(config.token)
我不知道为什么 ytdl 不能播放很多歌曲,但我用 trycatch 修复了它,所以它不会让我的机器人崩溃,有趣的是我不想播放的视频播放不是私人的,也不是很长,ytdl 由于某种原因在很多视频方面存在很多问题
我用 Node.js 和 YTDl-Core 为 Discord 写了一个音乐机器人。我可以播放 YouTube 上的每一首歌曲,但有一个限制,如果我播放一个 song/video 的频道,它很少将其添加到队列中,但无法播放并且机器人离开了 VoiceChannel,但我没有'得到一个错误,如果我尝试使用它完全工作的机器人,那么只要我坚持这个限制。这是我的代码:
const Discord = require('discord.js')
const fs = require('fs')
const ytdl = require('ytdl-core')
const ffmpeg = require('ffmpeg')
const { debug, Console } = require('console')
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
const ytapi3 = config.GoogleApiYT3
const search = require('youtube-search')
const { getInfo } = require('ytdl-core')
const queue = new Map()
var client = new Discord.Client()
//setting status
client.on('ready', () => {
console.log("Logged in as", client.user.username, "...")
client.user.setPresence({
status: config.status,
activity: {
name: config.activity,
type: 'STREAMING',
url: config.streamingURL
}
})
})
//musicbot
client.on('message', async message => {
if(message.author.bot) return // test if bot has written this message
if(!message.channel.id == config.botcommandsChannelID) return //test if message is in botcommands channel
if(!message.content.startsWith(config.prefix)) return // test if prefix is used
const args = message.content.substring(config.prefix.length).split(" ") // split arguments into args[]-list and cut the prefix out
const voiceChannel = message.member.voice.channel
const serverqueue = queue.get(message.guild.id)
//test if user has permissions to use command
if(config.UseDJRole == "true") {
if(message.member.roles.cache.has(config.DJroleID) || message.member.roles.cache.has(config.ModeratorRoleID) || message.member.user.id == config.owner){
}else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToUseThisCommand)
}
}
if(!voiceChannel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_404) //testing if user is in voiceChannel
if(message.content.startsWith(config.prefix + config.PlayCommand)){ //Play-case
const permission = voiceChannel.permissionsFor(message.client.user)
if(!permission.has('CONNECT')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToJoinVC)
if(!permission.has('SPEAK')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToSpeakInVC)
var song = {
url: null,
title: null
}
//get link "song"
if(args.length >= 2){
if(ytdl.validateURL(args[1])){
args.shift()
try{
song = await searchOnYT(args[0], message.channel);
}catch(error){
return console.log("returned")
}
} else{
args.shift()
const vidSearchLink = args.join(' ')
try{
song = await searchOnYT(vidSearchLink, message.channel);
} catch(error){
return console.log("returned")
}
}
}else {
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoArgs)
}
if(!serverqueue){
const queueConstruct = {
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: config.musicDefaultVolume,
playing: true
}
queue.set(message.guild.id, queueConstruct)
queueConstruct.songs.push(song)
try {
queueConstruct.connection = await voiceChannel.join()
play(message.guild, queueConstruct.songs[0], message)
} catch (error) {
console.log(error)
queue.delete(message.guild.id)
return sendEmbed(message.channel, config.ErrorColor, "Error", config.ErrorDuringConnectingToVoiceChannel)
}
}else{
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id){
return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)
} else{
try {
_url = song.url
//add to queue
serverqueue.songs.push(song)
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Adding", song.title + config.addedToQueue, _url)
} catch (error) {
console.log(error)
return sendEmbed(message.channel, config.ErrorColor, "Error", config.ErrorDuringAddingToQueue)
}
}
}
return undefined
}else if(message.content.startsWith(config.prefix + config.StopCommand) || message.content.startsWith(config.prefix + config.LeaveCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
serverqueue.songs = []
serverqueue.connection.dispatcher.end()
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Stopping", config.stoped)
}else if(message.content.startsWith(config.prefix + config.PauseCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
if(!serverqueue.playing) return sendEmbed(message.channel, config.ErrorColor, "Error", config.AllredyPaused)
serverqueue.playing = false
serverqueue.connection.dispatcher.pause()
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Pausing", config.Paused)
}else if(message.content.startsWith(config.prefix + config.ResumeCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
if(serverqueue.playing) return sendEmbed(message.channel, config.ErrorColor, "Error", config.AllredyPlaying)
serverqueue.playing = true
serverqueue.connection.dispatcher.resume()
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Resuming", config.Resumed)
}else if(message.content.startsWith(config.prefix + config.SkipCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
serverqueue.connection.dispatcher.end()
return console.log("skipped")
}else if(message.content.startsWith(config.prefix + config.QueueCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)//test if you are in one voice channel with the bot
if(serverqueue){
if(serverqueue.playing){
var status = config.Resumed
}else{
var status = config.Paused
}
const embedMessage = new Discord.MessageEmbed()
.setColor(config.MusicEmbedColorHEX)
.setTitle("Queue | volume(" + serverqueue.volume + "/5)" + status)
for (let index = 0; index < serverqueue.songs.length; index++) {
embedMessage.addField(serverqueue.songs[index].title, serverqueue.songs[index].url)
}
return message.channel.send(embedMessage)
} else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue)
}
}else if(message.content.startsWith(config.prefix + config.VolumeCommand) || message.content.startsWith(config.prefix + config.VCommand)){
if(!serverqueue) return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoMusicInQueue) //test if something playing
if(voiceChannel.id != queue.get(message.guild.id).voiceChannel.id) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)//test if you are in one voice channel with the bot
if(!args[1]){
if(serverqueue.volume == 0){
var v = config.VMute
}else{
var v = config.VUnMute
for (let index = 0; index < serverqueue.volume; index++) {
v = v + config.VSymbol
}
}
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Volume (" + serverqueue.volume + "/5)", v) //return volume
}
if(args[1] == "+" || args[1] == "plus"){
if(serverqueue.volume == 5) return sendEmbed(message.channel, config.ErrorColor, "Error", config.MaxVolume)
serverqueue.volume = serverqueue.volume + 1
if(serverqueue.volume == 0){
var v = config.VMute
}else{
var v = config.VUnMute
for (let index = 0; index < serverqueue.volume; index++) {
v = v + config.VSymbol
}
}
serverqueue.connection.dispatcher.setVolumeLogarithmic(serverqueue.volume / 5)
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Volume (" + serverqueue.volume + "/5)", v) //return volume
}else if(args[1] == "-" || args[1] == "minus"){
if(serverqueue.volume == 0) return sendEmbed(message.channel, config.ErrorColor, "Error", config.MinVolume)
serverqueue.volume = serverqueue.volume - 1
if(serverqueue.volume == 0){
var v = config.VMute
}else{
var v = config.VUnMute
for (let index = 0; index < serverqueue.volume; index++) {
v = v + config.VSymbol
}
}
serverqueue.connection.dispatcher.setVolumeLogarithmic(serverqueue.volume / 5)
return sendEmbed(message.channel, config.MusicEmbedColorHEX, "Volume (" + serverqueue.volume + "/5)", v) //return volume
}else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.VSyntax) //return volume
}
}
})
function sendEmbed(_channel, _Color, _Title, _Description, _URL){
const embedMessage = new Discord.MessageEmbed()
.setColor(_Color)
.setTitle(_Title)
.setDescription(_Description)
.setURL(_URL);
_channel.send(embedMessage)
}
function searchOnYT(searchstring, _channel){
var opts = {
maxResults: 1,
key: config.GoogleApiYT3,
type: 'video'
}
return new Promise((resolve, reject) => {
search(searchstring, opts, function(err, results) {
if(err) reject(err);
if(results) {
const r = results[0]
u = r.link
t = r.title.replaceAll(""", '"').replaceAll("&", "&")
var ar = {
url: u,
title: t
}
resolve(ar)
}
else {
sendEmbed(_channel, config.ErrorColor, "Error", config.NoResultsFound+ searchstring);
var e = new Error(["no videofound"])
reject(e)
}
})
});
}
function play(guild, song, message){
const serverqueue = queue.get(guild.id)
if(!song){
serverqueue.voiceChannel.leave()
queue.delete(guild.id)
client.user.setPresence({
status: config.status,
activity: {
name: config.activity,
type: 'STREAMING',
url: config.streamingURL
}
})
return (message.channel, config.MusicEmbedColorHEX, "Stopping", config.PlayedQueueTrough)
}
client.user.setPresence({
status: config.status,
activity: {
name: "Music",
type: 'STREAMING',
url: serverqueue.songs[0].url
}
})
const dispatcher = serverqueue.connection.play(ytdl(song.url))
.on('finish', () => {
serverqueue.songs.shift()
play(guild, serverqueue.songs[0], message)
})
.on('error', error => {
console.log(error)
})
dispatcher.setVolumeLogarithmic(serverqueue.volume / 5)
sendEmbed(message.channel, config.MusicEmbedColorHEX, "Playing", config.startPlaying + serverqueue.songs[0].title, serverqueue.songs[0].url)
}
client.login(config.token)
我不知道为什么 ytdl 不能播放很多歌曲,但我用 trycatch 修复了它,所以它不会让我的机器人崩溃,有趣的是我不想播放的视频播放不是私人的,也不是很长,ytdl 由于某种原因在很多视频方面存在很多问题