discord.py中repeat命令无法实现音乐无限循环的技术问询
Hey there! Let's break down why your repeat command isn't working as expected and fix it step by step.
Immediate Issues in Your Current Code
First, let's tackle the small but critical problems in your existing repeat command:
is_playingis a method, not a property
In your checkif not voice.is_playing:, you're referencing the method object instead of calling it. This means the condition will never trigger (since the method exists even if no audio is playing). You need to call it with parentheses:voice.is_playing().Missing a check for an active voice connection
If the bot isn't connected to any voice channel in the guild,voicewill beNone, and trying to accessvoice.is_playing()will throw an error. Always verify the voice client exists first.
The Core Problem: voice.loop Doesn’t Auto-Restart Audio by Default
Discord.py’s VoiceClient.loop property is just a flag—it doesn’t automatically make audio repeat on its own. You need to add an after callback to your play command that checks this flag and restarts the audio when it finishes playing.
Fixed Code Examples
1. Updated repeat Command
We’ll fix the checks and make the command toggle the loop state (more user-friendly than only enabling it):
@bot.command(pass_context=True) async def repeat(ctx): voice = get(bot.voice_clients, guild=ctx.guild) # Verify bot is connected and playing audio if not voice or not voice.is_playing(): return await ctx.send('Aucune musique joué !') # Toggle loop on/off voice.loop = not voice.loop status = "activé" if voice.loop else "désactivé" await ctx.send(f"La répétition est {status}\nPour l'inverser, utilisez `!repeat` à nouveau") await ctx.message.add_reaction('✅')
2. Modified play Command to Support Looping
Your play command needs an after callback that restarts the audio if looping is enabled. Here’s how to implement it:
@bot.command() async def play(ctx, *, url): # Check if user is in a voice channel if not ctx.author.voice: return await ctx.send("Tu n'es pas dans un canal vocal !") voice_channel = ctx.author.voice.channel voice = get(bot.voice_clients, guild=ctx.guild) # Connect or move to the user's voice channel if not voice: voice = await voice_channel.connect() elif voice.channel != voice_channel: await voice.move_to(voice_channel) # Create the audio source source = await discord.FFmpegOpusAudio.from_probe(url) # Callback to restart audio if loop is enabled def after_playing(error): if error: print(f"Erreur lors de la lecture : {error}") # Restart playback only if loop is on and bot is still connected if voice and voice.loop: voice.play(source, after=after_playing) # Start playing with the loop-aware callback voice.play(source, after=after_playing) await ctx.send(f"Lecture démarrée : {url}")
Why This Works
- The
aftercallback runs immediately after the audio finishes. It checks ifvoice.loopis enabled, and if so, restarts the same audio source. - The updated
repeatcommand safely validates the bot’s state before making changes, and gives users control to toggle looping on or off.
内容的提问来源于stack exchange,提问作者bey ptitloup

