【问题标题】:Music not playing in Discord voice channel音乐未在 Discord 语音频道中播放
【发布时间】:2022-07-10 00:07:35
【问题描述】:

我正在尝试将播放音乐的功能添加到我的自定义 Discord 机器人中。 我正在用 Java 11、Spring Boot、Discord4j 和 LavaPlayer 库编写它。

我有命令 !join 让 Discord 机器人加入输入命令的人的语音频道。这可行,但一旦机器人加入,我将LavaPlayerAudioProvider 分配给VoiceState。所以这里可能会出现错误(我不知道)。这是 !join 命令的类:

@RequiredArgsConstructor
public class JoinCommandHandler implements CommandStrategy {
    private final LavaPlayerAudioProvider provider;

    /**
     * {@inheritDoc}
     * <p>
     * Makes the bot join the voice channel of the user.
     */
    @Override
    public Mono<Void> execute(Message message) {
        return Mono.just(message)
                .flatMap(Message::getAuthorAsMember)
                .flatMap(m -> m.getVoiceState()
                        .flatMap(VoiceState::getChannel))
                .flatMap(c -> c.join(spec -> spec.setProvider(provider)))
                .then();
    }

    @Override
    public String getCommandName() {
        return "!join";
    }

    @Override
    public String getDescription() {
        return "**Under Development** Make this bot join your channel.";
    }
}

老实说,我认为错误不会出现在 !join 命令中,但更多地理解这个问题可能会有所帮助。

我在AudioConfig 类中设置了这样的音频配置:

@Configuration
public class AudioConfig {
    @Bean
    public AudioPlayerManager audioPlayerManager() {
        final AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
        playerManager.getConfiguration().setFrameBufferFactory(NonAllocatingAudioFrameBuffer::new);
        AudioSourceManagers.registerLocalSource(playerManager);
        return playerManager;
    }

    @Bean
    public AudioPlayer audioPlayer() {
        return audioPlayerManager().createPlayer();
    }

    @Bean
    public AudioProvider audioProvider() {
        return new LavaPlayerAudioProvider(audioPlayer());
    }
}

我写了一个 !play [youtube url] 命令来在机器人加入语音频道后播放音乐。

@Service("!play")
@RequiredArgsConstructor
public class PlayCommand implements CommandStrategy {
    private final AudioPlayerManager manager;
    private final TrackScheduler trackScheduler;

    /**
     * {@inheritDoc}
     * <p>
     * Makes the bot queue a song and play in the channel.
     */
    @Override
    public Mono<Void> execute(Message message) {
        return Mono.just(message.getContent())
                .map(content -> Arrays.asList(content.split(" ")))
                .doOnNext(command -> manager.loadItem(command.get(1), trackScheduler)).then();
    }
}

这里是LavaPlayerAudioProviver 来提供音乐:

@Component
public final class LavaPlayerAudioProvider extends AudioProvider {
    private final AudioPlayer audioPlayer;
    private final MutableAudioFrame frame = new MutableAudioFrame();

    public LavaPlayerAudioProvider(AudioPlayer audioPlayer) {
        super(ByteBuffer.allocate(StandardAudioDataFormats.DISCORD_OPUS.maximumChunkSize()));
        this.frame.setBuffer(getBuffer());
        this.audioPlayer = audioPlayer;
    }

    @Override
    public boolean provide() {
        final boolean didProvide = audioPlayer.provide(frame);
        if (didProvide) {
            getBuffer().flip();
        }
        return didProvide;
    }
}

现在棘手的部分来了。我调试了代码,以便在我键入 !play [url] 命令后逐步查看代码是如何执行的。

当代码到达TrackScheduler类时,它并没有执行trackLoaded()方法来播放歌曲,而是执行noMatches()方法,这基本上意味着找不到URL,因此没有音乐可以播放。你可以在这里找到TrackScheduler 类:

@Component
@RequiredArgsConstructor
public class TrackScheduler implements AudioLoadResultHandler {
    private final AudioPlayer player;

    @Override
    public void trackLoaded(final AudioTrack track) {
        // LavaPlayer found an audio source for us to play
        player.playTrack(track);
    }

    @Override
    public void playlistLoaded(final AudioPlaylist playlist) {
        // LavaPlayer found multiple AudioTracks from some playlist
    }

    @Override
    public void noMatches() {
        // LavaPlayer did not find any audio to extract
    }

    @Override
    public void loadFailed(final FriendlyException exception) {
        // LavaPlayer could not parse an audio source for some reason
    }
}

我尝试了不同的 URL,但它们最终都进入了 noMatch() 方法...... 我遵循了 Discord4J 指南 (https://docs.discord4j.com/music-bot-tutorial),但他们没有使用 Spring Boot,所以这有点困惑..

如果您需要更多信息,我很乐意提供给您。 提前谢谢各位!

【问题讨论】:

    标签: java spring-boot discord discord4j lavaplayer


    【解决方案1】:

    好的,我知道有点晚了,但请继续。

    您的问题是,您只为音频播放器注册本地资源。这意味着,lavaplayer 不知道像 FacebookYoutubeVimeo 这样的网站是什么以及如何处理它们。

    您应该将AudioSourceManagers.registerRemoteSources(audioPlayerManager); 添加到您的配置类中。

    所以最终的配置类将如下所示:

    @Configuration
    public class AudioConfig {
        @Bean
        public AudioPlayerManager audioPlayerManager() {
            final AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
            playerManager.getConfiguration().setFrameBufferFactory(NonAllocatingAudioFrameBuffer::new);
            AudioSourceManagers.registerLocalSource(playerManager);
            AudioSourceManagers.registerRemoteSources(audioPlayerManager);
            return playerManager;
        }
    
        @Bean
        public AudioPlayer audioPlayer() {
            return audioPlayerManager().createPlayer();
        }
    
        @Bean
        public AudioProvider audioProvider() {
            return new LavaPlayerAudioProvider(audioPlayer());
        }
    }
    

    除此之外,您的代码对我来说很好用。我建议完全删除AudioSourceManagers.registerLocalSource(playerManager);,我看不出有任何理由以这种方式公开服务器端文件。

    【讨论】:

      猜你喜欢
      • 2022-01-04
      • 2019-01-11
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      • 2019-09-14
      • 2020-08-17
      • 1970-01-01
      • 2020-11-09
      相关资源
      最近更新 更多