首页 > 解决方案 > 使用 discord.js 和 ytdl API 通过机器人播放音乐时的性能问题

问题描述

我正在使用discord.js api 制作音乐机器人,但我在播放音乐命令中遇到了性能问题。例如,如果机器人正在通话中播放某些东西,而我使用添加音乐命令,机器人会滞后几秒钟。我认为很多问题出在我用来获取音乐的 api 中,但我不确定。如果错误编写的代码通常会降低性能,如果您能帮助我,我将不胜感激。我正在使用ytdl api 来获取普通视频和ytpl来获取播放列表。这是整个命令:

const timelabel = require('timelabel')
const ytdl = require('ytdl-core')
const { Client, StreamDispatcher } = require('discord.js');
const client = new Client();
const ytpl = require('ytpl');
const Discord = require("discord.js")

const queue = new Map(); // Cada server vai ter um map (queue) diferente
//(message, guild.id, queue_constructor { voice channel, text channel, connection, song[]})

module.exports = {
    commands: ['play', 'p '],
    expectedArgs: '<url do video>',
    permissionError: '',
    minArgs: 1,
    maxArgs: null,
    callback: async (message, arguments, text) => {
        if (message.channel.id === '753413520606887967') return;

        const serverQueue = await queue.get(message.guild.id);
        const voice_channel = await message.member.voice.channel;
        const bot_channel = await message.guild.me.voice.channel;


        if(!voice_channel) return message.channel.send('Voce precisa estar em uma call pra usar esse comando troxa')

        if (bot_channel && bot_channel !== voice_channel) return message.channel.send(
                "Você precisa estar na mesma call que o bot para usar esse comando burro")
            
        const videoFinder = async (arguments) => {
            const videoResult = await ytSearch(`${arguments}`);
            // Se tiver mais de um resultado pro video, vai retornar o primeiro
            return (videoResult.videos.length > 1) ? videoResult.videos[0] : null
        }
        
        const videoFinderPlaylist = async (arguments) => {
            const playlistResult = await ytpl(`${arguments}`);
            return (playlistResult) ? playlistResult : null
        }
        const video = await videoFinder(arguments.join(' '));

        if (!video) {
            try {
                var playlist = await videoFinderPlaylist(arguments.join(' '));
            } catch (err) {
                return message.channel.send("Houve algum erro procurando esse link. Sugiro retirar **&ab_channel...** do link caso tiver algum.");
            }
        }
        if (video) {
            song = 
            {
                title: video.title, 
                url: video.url,
                videoLength: video.duration.timestamp,
                seconds: video.duration.seconds,
                thumbnail: video.thumbnail,
                author: video.author.name,
                userRequested: message.author.toString()

            }
            

        } else if (playlist) {
            song = [];
            for (let i = 0; playlist.items.length > i; i++) {
                playlistSongs = 
                {
                    index: playlist.items[i].index,
                    title: playlist.items[i].title,
                    url: playlist.items[i].shortUrl,
                    videoLength: playlist.items[i].duration,
                    seconds: playlist.items[i].durationSec,
                    thumbnail: playlist.items[i].thumbnails[0].url,
                    author: playlist.items[i].author.name,
                    userRequested: message.author.toString()
                }
                song.push(playlistSongs);
            }
        }
    if (!serverQueue) {
        const queueConstructor = 
        {
            voice_channel: voice_channel,
            text_channel: message.channel,
            connection: null,
            songs: []
        }

        queueConstructor.songs = queueConstructor.songs.concat(song);
        queue.set(message.guild.id, queueConstructor);

        try {
            const connection = await voice_channel.join();
            queueConstructor.connection = connection;
            videoPlay(message.guild, queueConstructor.songs[0].url);
        } catch (err) {
            queue.delete(message.guild.id);
            message.channel.send('Houve um erro ao tentar se conectar à call');
            console.log(err);
        }
    } else {
        // get last element from the array
        last = serverQueue.songs.length
        serverQueue.songs = serverQueue.songs.concat(song);
        let embed = new Discord.MessageEmbed()
        .setColor("#73ffdc")
        .setTitle("Adicionado á fila ♪&quot;)
        .setThumbnail(serverQueue.songs[last].thumbnail)
        .setDescription(`[${serverQueue.songs[last].title}](${serverQueue.songs[last].url})`)
        .addFields(
        {"name": "Canal", "value": serverQueue.songs[last].author, inline: true},
        {"name": "Duração", "value": serverQueue.songs[last].videoLength, inline: true},
        {"name": "\u200B","value": "`Requested by: `" + `${serverQueue.songs[last].userRequested}`});
        EmbedMsg = serverQueue.text_channel.send(embed)
    }
},
    permissions: '',
    requiredRoles: [],
}

const videoPlay = async (guild, song) => {
    const songQueue = queue.get(guild.id)
    module.exports.songQueue = queue.get(guild.id)
    let embed = new Discord.MessageEmbed();
    // Se a queue ta vazia
    if (!song) {
        return queue.delete(guild.id)
    }
    //console.log(songQueue.connection)
    const stream =  ytdl(song, { filter: 'audioonly' });
    const dispatcher = await songQueue.connection.play(stream, { seek: 0, volume: 0.5, filter: "audioonly"})
    .on('speaking', () =>{
        module.exports.tempo = dispatcher.streamTime
    })
    .on ('finish', () => {
        // Quando acaba a musica da shift para proxima da queue
        try {
            embedMsgID.delete();
        } catch (err) {
            console.log(err)
        }
        songQueue.songs.shift();
        return (songQueue.songs.length > 0) ? videoPlay(guild, songQueue.songs[0].url) : videoPlay(guild, false);
    })
    .on('error', err => {
        songQueue.text_channel.send(`Houve um erro enquanto tocava **${songQueue.songs[0].title}**`);
        songQueue.songs.shift();
        return (songQueue.songs.length > 0) ? videoPlay(guild, songQueue.songs[0].url) : videoPlay(guild, false)
    })

    if (songQueue.songs.length > 0) {
        embed
        .setColor("#73ffdc")
        .setTitle("Tocando agora ♪&quot;)
        .setThumbnail(songQueue.songs[0].thumbnail)
        .setDescription(`[${songQueue.songs[0].title}](${songQueue.songs[0].url})`)
        .addFields(
        {"name": "Canal", "value": songQueue.songs[0].author, inline: true},
        {"name": "Duração", "value": songQueue.songs[0].videoLength, inline: true},
        {"name": "\u200B","value": "`Requested by: `" + `${songQueue.songs[0].userRequested}`});
        embedMsg = await songQueue.text_channel.send(embed)
        embedMsgID = embedMsg;
    } else {
        return;
    }
}

标签: javascriptnode.js

解决方案


推荐阅读