javascript - FFMpeg Discordjs Music Bot 在随机时间后随机停止播放音乐

标签 javascript ffmpeg discord discord.js opus

我的音乐机器人会随机停止播放音乐并转到队列中的下一首歌曲。我该如何阻止这种情况发生?我已经提供了我的代码以及发生这种情况时在控制台中出现的错误。我试过改变 ffmpeg_options (我不确定我是否做错了)。我只是想让这个错误在理想情况下停止发生 - 我真的很感激任何帮助!
编辑:我正在使用节点 v16.13.0
这是我的代码:

const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const { joinVoiceChannel, createAudioPlayer, createAudioResource } = require('@discordjs/voice');
const { leaveVoiceChannel } = require('@discordjs/voice');
const { execute } = require('./togglepeenie');
const voice = require('@discordjs/voice');
const { MessageEmbed } = require('discord.js');

const queue = new Map();
var player;
var thumbnail;
var link;
var songName;
let song = {};
let connection;
var date;
var startTime;

ffmpeg_options = {
    'options': '-vn',
    "before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5"
}

//queue(message.guild.id, queue_constructor object {voice channel, text channel, connection, song[]});
module.exports = {
    name: 'play',
    aliases: ['p', 'skip', 's', 'stop', 'pause', 'state', 'nowplaying', 'np'],
    description: 'Handles all music bot commands.',
    
    async execute(message, args, cmd, client, Discord) {

        const voice_channel = message.member.voice.channel;
        if (!voice_channel) return message.channel.send('You need to be in a channel to execute this command!');
        const permissions = voice_channel.permissionsFor(message.client.user);
        if (!permissions.has('CONNECT')) return message.channel.send('You don\'t have the correct permissions. :(');
        if (!permissions.has('SPEAK')) return message.channel.send('You don\'t have the correct permissions. :(');

        const server_queue = queue.get(message.guild.id);
        

        if (cmd === 'play' || cmd === 'p'){ 
            if (!args.length) {
                //if no args, try to play paused song
                if (!player || player.state.status === 'idle') return message.channel.send(`<:x2:906412004632326154> **Nothing is playing** <:peeposad:875207109703262258>`);
                if (player.state.status === 'playing') return message.channel.send(`<:x2:906412004632326154> **The player is not paused** <:peeposad:875207109703262258>`);

                player.unpause();
                return message.channel.send(`:play_pause: **Resuming** :thumbsup:`);
            }
            //let song = {};

            //if url, search the url
            if (ytdl.validateURL(args[0])) {
                const song_info = await ytdl.getInfo(args[0]);
                song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url, image: song_info.videoDetails.thumbnail, seconds: song_info.videoDetails.timestamp, duration: song_info.videoDetails.duration}
                //thumbnail = song.image;
                //songName = song.title;
                //link = song.url;
            } 
            //if keywords, search video with keywords
            else {
                const videoFinder = async (query) => {
                    const videoResult = await ytSearch(query);
                    return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
                }

                const video = await videoFinder(args.join(' '));
                if (video) {
                    song = { title: video.title, url: video.url, image: video.thumbnail, seconds: video.timestamp, duration: video.duration }
                    //thumbnail = song.image;
                    //songName = song.title;
                    //link = song.url;
                } else {
                    return message.reply('No video results found. :(');
                }
            }//END OF KEYWORD SEARCH

            //If there isn't a queue, start a queue. message can be like "now playing".
        if (!server_queue) {
            const queue_constructor = {
                voice_channel: voice_channel,
                text_channel: message.channel,
                connection: null,
                songs: []
            }

            queue.set(message.guild.id, queue_constructor);
            queue_constructor.songs.push(song);

            try {
                connection = await joinVoiceChannel({
                    channelId: voice_channel.id,
                    guildId: message.guild.id,
                    adapterCreator: message.guild.voiceAdapterCreator
                });
                queue_constructor.connection = connection;
                video_player(message.guild, queue_constructor.songs[0]);
            } catch (err) {
                queue.delete(message.guild.id);
                message.channel.send('There was an error connecting!');
                throw err;
            }

            //if there IS a queue, add to the queue. Message can be something like "added to queue."
        } else {
            server_queue.songs.push(song);
            return message.reply(`:thumbsup: **${song.title} added to queue!**`);
        }

        }//====================================
        //END OF PLAY COMMAND / P ALIAS

        else if(cmd === 'pause') {
            if (!player || player.state.status === 'idle') {
                return message.channel.send(`<:x2:906412004632326154> **Nothing is currently playing** <:peeposad:875207109703262258>`);
            }
            if (player.state.status === 'paused') return message.channel.send(`<:x2:906412004632326154> **The player is already paused** <:peeposad:875207109703262258>`);
            player.pause();
            message.channel.send(`**Paused** :pause_button:`);
        }
        else if(cmd === 'state') {
            if(!player) return console.log('No player.');
            console.log(player.state.status);
        }
        else if(cmd === 'skip' || cmd === 's') {
            if (!server_queue){
                return message.channel.send(`<:x2:906412004632326154> **Nothing is currently playing** <:peeposad:875207109703262258>`);
            }
            message.channel.send(`:fast_forward: ***Skipped*** :thumbsup:`);
            skip_song(message, server_queue);
        }
        else if(cmd === 'np' || cmd === 'nowplaying') {
            if(!player || player.state.status === 'idle' || player.state.status === 'buffering') return message.channel.send(`<:x2:906412004632326154> **Nothing is currently playing** <:peeposad:875207109703262258>`);
            var currentTime;
            console.log(player.state.status);
            date = new Date();
            var rawTime = date.valueOf() - startTime;
            var time = getReadableTime(rawTime);
            var totalDuration = song.seconds;
            const embed = new MessageEmbed()
            .setColor('#edc937')
            .setAuthor('Now Playing ♪', `https://i.imgur.com/CXQGtpF.png`)
            .setDescription(`${songName}`, link)
            .setThumbnail(`${thumbnail}`)
            .addFields(
                { name: `${time} / ${totalDuration}`, value: '\u200b' },
            )
            .setTimestamp()
            .setFooter('`Requested by: `' + `${message.author.id}`);
        message.channel.send({embeds: [embed]})
        }//END OF NOW PLAYING

        

    }//END OF EXECUTE ON CMD RUN
    
    
}
var song_queue;
const video_player = async (guild, song) => {
    song_queue = queue.get(guild.id);

    if (!song) {
        player.stop();
        //player.delete();
        await voice.getVoiceConnection(guild.id).disconnect();
        queue.delete(guild.id);
        return;
    }
    thumbnail = song_queue.songs[0].image;
    link = song_queue.songs[0].url;
    songName = song_queue.songs[0].title;

    const stream = ytdl(song.url, {filter: 'audioonly'});
    
    player = createAudioPlayer();
    const resource = createAudioResource(stream);
    

    player.play(resource);
    song_queue.connection.subscribe(player);
    var currentState = player.state;
    //console.log(currentState);

    date = new Date();
    startTime = date.valueOf();

    player.on('idle', () => {
    song_queue.songs.shift(),
    video_player(guild, song_queue.songs[0])
    });

    //setTimeout(() => song_queue.songs.shift(), video_player(guild, song_queue.songs[0]),  10000);

    
    await song_queue.text_channel.send(`Now playing **${song.title}**`)
   
}

const skip_song = (message, server_queue) => {
    if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
    
    song_queue.songs.shift();
    video_player(message.guild, song_queue.songs[0]);
    
}

const getReadableTime = (rawTime) => {
    var totalSeconds = Math.floor(rawTime / 1000) - 1;
    var totalMinutes = Math.floor(totalSeconds / 60);
    var hours = Math.floor(totalMinutes / 60);
    var minutes = totalMinutes % 60;
    var seconds = totalSeconds % 60;
    if (seconds < 10) {
        seconds = `0${seconds}`;
    }
    if (hours == 0) {
        hours = '';
    } else if (hours < 10) {
        hours = `0${hours}:`;
    } else {
        hours = `${hours}:`;
    }

    return `${hours}${minutes}:${seconds}`;
}
这是我每次中断时得到的错误:
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: OggDemuxer {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 5,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      _remainder: null,
      _head: null,
      _bitstream: null,
      [Symbol(kCapture)]: false,
      [Symbol(kCallback)]: [Function: bound onwrite]
    },
    edges: [ [Object], [Object] ],
    metadata: null,
    volume: undefined,
    encoder: undefined,
    audioPlayer: H {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      _state: [Object],
      subscribers: [Array],
      behaviors: [Object],
      debug: [Function (anonymous)],
      [Symbol(kCapture)]: false
    },
    playbackDuration: 563720,
    started: true,
    silencePaddingFrames: 5,
    silenceRemaining: -1
  }
}```

最佳答案

尝试使用 play-dl而不是 ytdl-core如果您不想降级节点版本。

关于javascript - FFMpeg Discordjs Music Bot 在随机时间后随机停止播放音乐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69875288/

相关文章:

hadoop - 使用 WebHDFS 通过 HTTP 播放视频

FFMPEG - 在执行前预览 FFMPEG 命令语法

javascript - Discord.js GuildMember.hasPermission?

javascript - 为什么我不能让汉堡菜单正常工作?

javascript - ReactJS 中的错误 "Assignment to constant variable"

javascript - 使用纯JS计算布局

ffmpeg:放大正方形图像

java - Discord OAuth2 重定向 URL 无法使用 JavaFX WebView JDK12 显示

discord - 如何通过代理连接不和谐机器人

javascript - 我一直在尝试用 javascript 制作一个时钟,但有时它显示为未定义