首页 > 解决方案 > 有没有办法我可以制作一种 One way vc bot 的东西

问题描述

你好,有没有办法让它这样你就可以有一个 1 路 vc 哪里(到目前为止我是如何设置的)2 个帐户以某种方式连接(我让 2 个能够从一个 jda 项目运行)然后有一个机器人在一个 vc 中,另一个在另一个 vc 中。第一个机器人听到了 vc 所说的内容,然后第二个机器人在第二个 vc 中分享了该内容,因此第一个 vc 中的人听不到第二个 vc 中的人,但第二个 vc 中的人可以听到第二个 vc 中的人第一个vc

顺便说一句,这就是我在一个 jda 项目 Main.java 中连接 2 个机器人的方式:

public class Main {

    public static void main(String[] args){
        Bot bot = new Bot("token for bot 1");
        Bot2 bot2 = new Bot2("token for bot 2");
        bot.start();
        bot2.start();
    }

}

Bot.java:

import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.hooks.ListenerAdapter;

import javax.security.auth.login.LoginException;

public class Bot {

    ListenerAdapter[] listenerAdapters= new ListenerAdapter[]{new Help()};
    String token;

    public Bot(String token) {
        this.token = token;
    }

    public void start() {
        JDABuilder jdaBuilder = JDABuilder.createDefault(token);
        jdaBuilder.addEventListeners(listenerAdapters);
        jdaBuilder.setActivity(Activity.watching("1!help"));

        try {
            JDA jda = jdaBuilder.build();
            jda.awaitReady();
        }   catch (LoginException | InterruptedException e){
                e.printStackTrace();
        }

    }

}

Bot2.java:

    import commands2.*;
    import net.dv8tion.jda.api.entities.Activity;
    import net.dv8tion.jda.api.JDA;
    import net.dv8tion.jda.api.JDABuilder;
    import net.dv8tion.jda.api.hooks.ListenerAdapter;
    
    import javax.security.auth.login.LoginException;
    
    public class Bot2 {
    
        ListenerAdapter[] listenerAdapters = new ListenerAdapter[]{new Help2()};
        String token;
    
        public Bot2(String token) {
            this.token = token;
        }
    
        public void start() {
            JDABuilder jdaBuilder = JDABuilder.createDefault(token);
            jdaBuilder.addEventListeners(listenerAdapters);
            jdaBuilder.setActivity(Activity.watching("2!help"));
        try {
            JDA jda = jdaBuilder.build();
            jda.awaitReady();
        }   catch (LoginException | InterruptedException e){
            e.printStackTrace();
        }

    }

}

谁有这个想法?(顺便说一句,我设置它的方式是我在intellij中运行它,然后两个机器人都可以工作)

标签: discord-jda

解决方案


我只会向您展示如何执行“从一个机器人到另一个机器人的流式音频”- 部分。
实现完全取决于您(以及您是想通过命令激活它还是希望机器人在启动时加入特定频道等)

为了能够跳过这一部分,我假设两个机器人都已经在他们的专用频道中。

在开始之前,您必须对现有代码进行一些更改,因为您以后可能需要它们:

import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.hooks.ListenerAdapter;

import javax.security.auth.login.LoginException;

public class Bot {

    ListenerAdapter[] listenerAdapters= new ListenerAdapter[]{new Help()};
    String token;

    // this is new
    JDA jda;

    public Bot(String token) {
        this.token = token;
    }

    public void start() {
        JDABuilder jdaBuilder = JDABuilder.createDefault(token);
        jdaBuilder.addEventListeners(listenerAdapters);
        jdaBuilder.setActivity(Activity.watching("1!help"));

        try {

            // and this changed as well
            this.jda = jdaBuilder.build();

            jda.awaitReady();
        }   catch (LoginException | InterruptedException e){
                e.printStackTrace();
        }

    }

}

我更改了代码,以便可以通过using访问JDA实例。当然,这些更改也必须进行。BotBot.jdaBot2

进行更改后,您必须实施一种方式让机器人加入其专用语音频道,但这取决于您。

您基本上想要的是将一个机器人的接收音频插入另一个机器人的发送音频。

幸运的是,JDA 提供了一个示例,说明如何让机器人播放接收到的音频。在那里,您可以找到课程EchoHandler

public static class EchoHandler implements AudioSendHandler, AudioReceiveHandler
{
    /*
        All methods in this class are called by JDA threads when resources are available/ready for processing.
        The receiver will be provided with the latest 20ms of PCM stereo audio
        Note you can receive even while setting yourself to deafened!
        The sender will provide 20ms of PCM stereo audio (pass-through) once requested by JDA
        When audio is provided JDA will automatically set the bot to speaking!
     */
    private final Queue<byte[]> queue = new ConcurrentLinkedQueue<>();

    /* Receive Handling */

    @Override // combine multiple user audio-streams into a single one
    public boolean canReceiveCombined()
    {
        // limit queue to 10 entries, if that is exceeded we can not receive more until the send system catches up
        return queue.size() < 10;
    }

    @Override
    public void handleCombinedAudio(CombinedAudio combinedAudio)
    {
        // we only want to send data when a user actually sent something, otherwise we would just send silence
        if (combinedAudio.getUsers().isEmpty())
            return;

        byte[] data = combinedAudio.getAudioData(1.0f); // volume at 100% = 1.0 (50% = 0.5 / 55% = 0.55)
        queue.add(data);
    }
/*
    Disable per-user audio since we want to echo the entire channel and not specific users.
    @Override // give audio separately for each user that is speaking
    public boolean canReceiveUser()
    {
        // this is not useful if we want to echo the audio of the voice channel, thus disabled for this purpose
        return false;
    }
    @Override
    public void handleUserAudio(UserAudio userAudio) {} // per-user is not helpful in an echo system
*/

    /* Send Handling */

    @Override
    public boolean canProvide()
    {
        // If we have something in our buffer we can provide it to the send system
        return !queue.isEmpty();
    }

    @Override
    public ByteBuffer provide20MsAudio()
    {
        // use what we have in our buffer to send audio as PCM
        byte[] data = queue.poll();
        return data == null ? null : ByteBuffer.wrap(data); // Wrap this in a java.nio.ByteBuffer
    }

    @Override
    public boolean isOpus()
    {
        // since we send audio that is received from discord we don't have opus but PCM
        return false;
    }
}

这门课基本上为您完成了所有艰苦的工作。您可以输入 anAudioReceiveHandler并将其插入AudioSendHandler具有所需结果的 an 中。
现在唯一剩下的就是实际去做。

您希望第二个机器人播放来自第一个机器人的音频,如下所示:

(注意:您必须从guildandguild2的 jda 实例中获取BotBot2。)

/*
    example for getting the guilds:

    Guild guild = bot.jda.getGuildById(GUILDID);
    Guild guild2 = bot2.jda.getGuildById(GUILDID);
*/

AudioManager audioManager = guild.getAudioManager();    // of Bot
AudioManager audioManager2 = guild2.getAudioManager();  // of Bot2

EchoHandler handler = new EchoHandler();

audioManager.setReceivingHandler(handler);
audioManager2.setSendingHandler(handler);

推荐阅读