英文:
What could be causing my Java Discord bot using Lavaplayer and Maven to not play music?
问题
I've translated the code-related parts of your message:
我正在为 Discord 编写一个音乐机器人。该程序成功找到并下载音乐,但不播放音乐。没有任何代码有效,即使完全复制自一个手册,其作者具有相似的版本,他的代码能够正常运行。进一步研究问题发现程序卡在以下代码行上(在堆栈跟踪之后):
player.startTrack(track, false);
如果将上面的行替换为以下内容,卡顿问题仍然存在:
player.playTrack(track);
我找到了几年前发布的信息,称一些平台限制了机器人的下载访问权限。我测试代码的指南是今年二月发布的。我认为问题出在我的一方。
此外,使用 /play 时,我尝试输入来自不同平台的链接和其中的音轨,但没有任何帮助。
也许我应该在代码中指定一些意图?
代码:
- 主要部分
public static void main(String[] args) throws Exception {
JDA jda = JDABuilder.createDefault(TOKEN).setChunkingFilter(ChunkingFilter.ALL)
.setMemberCachePolicy(MemberCachePolicy.ALL).enableIntents(GatewayIntent.GUILD_MEMBERS,
GatewayIntent.GUILD_MESSAGES,
GatewayIntent.GUILD_VOICE_STATES).build();
jda.addEventListener(new checker());
}
- AudioSendHandler
...
- TrackScheduler
...
- GuildMusicManager
...
- PlayerManager
...
- /play
...
I've provided the translations for the code-related portions. If you have any specific questions or need further assistance with your code, please feel free to ask.
英文:
I am writing a music bot for discord. The program successfully finds and downloads music, but does not play it. No code works, even completely copied from a manual, whose author has similar versions, and his code performs its function. Further study of the problem led to the fact that the program hangs on the line (after stacktrace):
player.startTrack(track, false);
Hanging also happens if you replace the line above with:
player.playTrack(track);
I found information published a few years ago that some platforms restricted access to downloads from them for bots. The guide I tested the code for was released in February of this year. I think the problem is on my side.
Also, when using /play, I tried to enter links to different platforms and tracks on them, but nothing helps.
Maybe i should specify some intentions in the code?
Code:
- Main
public static void main(String[] args) throws Exception {
JDA jda = JDABuilder.createDefault(TOKEN).setChunkingFilter(ChunkingFilter.ALL)
.setMemberCachePolicy(MemberCachePolicy.ALL).enableIntents(GatewayIntent.GUILD_MEMBERS,
GatewayIntent.GUILD_MESSAGES,
GatewayIntent.GUILD_VOICE_STATES).build();
jda.addEventListener(new checker());
}
- AudioSendHandler
public class AudioForwarder implements AudioSendHandler {
private final AudioPlayer player;
private final Guild guild;
private final ByteBuffer buffer = ByteBuffer.allocate(1024);
private final MutableAudioFrame frame = new MutableAudioFrame();
private int time;
public AudioForwarder(AudioPlayer player, Guild guild) {
this.player = player;
this.guild = guild;
frame.setBuffer(buffer);
}
@Override
public boolean canProvide() {
boolean canProvide = player.provide(frame);
if(!canProvide) {
time += 20;
if (time >= 300000) {
time = 0;
System.out.println("timeout");
guild.getAudioManager().closeAudioConnection();
}
} else {
time = 0;
}
return canProvide;
}
@Nullable
@Override
public ByteBuffer provide20MsAudio() {
final Buffer tmp = ((Buffer) buffer).flip();
return (ByteBuffer) tmp;
}
@Override
public boolean isOpus() {
return true;
}
}
- TrackScheduler
public class TrackScheduler extends AudioEventAdapter {
private final AudioPlayer player;
private final BlockingQueue<AudioTrack> queue = new LinkedBlockingQueue<>();
private boolean isRepeat = false;
public TrackScheduler(AudioPlayer player) {
this.player = player;
}
@Override
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
if(isRepeat) {
System.out.println("6");
player.startTrack(track.makeClone(), false);
System.out.println("7");
} else {
System.out.println("8");
player.startTrack(queue.poll(), false);
System.out.println("9");
}
}
public void queue(AudioTrack track) {
if(!player.startTrack(track, true)) {
System.out.println("1");
queue.offer(track);
System.out.println("2");
} else {
System.out.println("3");
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element:stackTraceElements) {
System.out.println(element.getMethodName());
}
player.startTrack(track, false);
System.out.println("4");
}
}
public AudioPlayer getPlayer() {
return player;
}
public BlockingQueue<AudioTrack> getQueue() {
return queue;
}
public boolean isRepeat() {
return isRepeat;
}
public void setRepeat(boolean repeat) {
isRepeat = repeat;
}
}
- GuildMusicManager
public class GuildMusicManager {
private TrackScheduler trackScheduler;
private AudioForwarder audioForwarder;
public GuildMusicManager(AudioPlayerManager manager, Guild guild) {
AudioPlayer player = manager.createPlayer();
trackScheduler = new TrackScheduler(player);
player.addListener(trackScheduler);
audioForwarder = new AudioForwarder(player, guild);
}
public TrackScheduler getTrackScheduler() {
return trackScheduler;
}
public AudioForwarder getAudioForwarder() {
return audioForwarder;
}
}
- PlayerManager
public class PlayerManager {
private static PlayerManager INSTANCE;
private final Map<Long, GuildMusicManager> guildMusicManagers = new HashMap<>();
private final AudioPlayerManager audioPlayerManager = new DefaultAudioPlayerManager();
private PlayerManager() {
AudioSourceManagers.registerRemoteSources(audioPlayerManager);
AudioSourceManagers.registerLocalSource(audioPlayerManager);
}
public static PlayerManager get() {
if(INSTANCE == null) {
INSTANCE = new PlayerManager();
}
return INSTANCE;
}
public GuildMusicManager getGuildMusicManager(Guild guild) {
return guildMusicManagers.computeIfAbsent(guild.getIdLong(), (guildId) -> {
GuildMusicManager musicManager = new GuildMusicManager(audioPlayerManager, guild);
guild.getAudioManager().setSendingHandler(musicManager.getAudioForwarder());
return musicManager;
});
}
public void play(Guild guild, String trackURL) {
GuildMusicManager guildMusicManager = getGuildMusicManager(guild);
audioPlayerManager.loadItemOrdered(guildMusicManager, trackURL, new AudioLoadResultHandler() {
@Override
public void trackLoaded(AudioTrack track) {
System.out.println("0");
guildMusicManager.getTrackScheduler().queue(track);
System.out.println("5");
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
System.out.println("0.1");
guildMusicManager.getTrackScheduler().queue(playlist.getTracks().get(0));
System.out.println("5.1");
}
@Override
public void noMatches() {
System.out.println("no_matches");
}
@Override
public void loadFailed(FriendlyException exception) {
System.out.println("failed");
}
});
}
}
- /play
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
if (event.getName().equals("play")) {
event.getGuild().getAudioManager().openAudioConnection(event.getMember().getVoiceState().getChannel());
String name = event.getOption("name").getAsString();
try {
new URI(name);
} catch (URISyntaxException e) {
name = name + "ytsearch:";
}
PlayerManager playerManager = PlayerManager.get();
event.reply("Playing").setEphemeral(true).submit();
playerManager.play(event.getGuild(), name);
}
}
After using /play, the bot successfully connects to the voice channel, but immediately starts reconnecting to it every few seconds without playing music.
On the discord developer portal, all intents are enabled, on the test server the bot has administrator rights, the role of the bot is prioritized above all others.
My versions:
JDA 5.0.0-alpha.11
lavaplayer 1.3.77
P.S. updated:
Moved to version of JDA 5.0.0-beta.9. The hanging is gone, but the program still doesn't play sound, and this time I don't understand what's going on there. Updated code above and screenshot of console output.
If you move the stacktrace to the place where the code reaches during /play:
答案1
得分: 0
After I upgraded to the latest version of JDA, the problem was due to incorrect program logic. Remove the else block in the question code:
Instead of:
public void queue(AudioTrack track) {
if(!player.startTrack(track, true)) {
System.out.println("1");
queue.offer(track);
System.out.println("2");
} else {
System.out.println("3");
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element:stackTraceElements) {
System.out.println(element.getMethodName());
}
player.startTrack(track, false);
System.out.println("4");
}
}
This:
public void queue(AudioTrack track) {
if(!player.startTrack(track, true)) {
queue.offer(track);
}
}
英文:
After I upgraded to the latest version of JDA, the problem was due to incorrect program logic. Remove the else block in the question code:
Instead of:
public void queue(AudioTrack track) {
if(!player.startTrack(track, true)) {
System.out.println("1");
queue.offer(track);
System.out.println("2");
} else {
System.out.println("3");
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element:stackTraceElements) {
System.out.println(element.getMethodName());
}
player.startTrack(track, false);
System.out.println("4");
}
}
This:
public void queue(AudioTrack track) {
if(!player.startTrack(track, true)) {
queue.offer(track);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论