【发布时间】: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