Discord音乐机器人报错求助:'Guild'对象无'voice_clientn'属性
问题排查与解决
核心错误原因
报错AttributeError: 'Guild' object has no attribute 'voice_clientn'是两个低级错误导致的:
- 拼写错误:你把Guild对象的
voice_client属性写成了voice_clientn(多了个末尾的n) - 错误调用方式:
voice_client是Guild的属性,不是方法,完全不需要传入server参数
另外你的代码还存在兼容性问题:create_ytdl_player方法在discord.py v1.0及以上版本已经被废弃,直接使用会引发新的错误。
修正后的完整代码
from discord.ext import commands import discord import asyncio from youtube_dl import YoutubeDL # 配置YTDL音频提取选项 ytdl_opts = { 'format': 'bestaudio/best', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], } ytdl = YoutubeDL(ytdl_opts) class YTDLSource(discord.PCMVolumeTransformer): def __init__(self, source, *, data, volume=0.5): super().__init__(source, volume) self.data = data self.title = data.get('title') self.url = data.get('url') @classmethod async def from_url(cls, url, *, loop=None, stream=False): loop = loop or asyncio.get_event_loop() data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream)) if 'entries' in data: data = data['entries'][0] filename = data['url'] if stream else ytdl.prepare_filename(data) return cls(discord.FFmpegPCMAudio(filename), data=data) players = {} @client.command(pass_context=True) async def play(ctx, url): server = ctx.guild # 检查用户是否在语音频道 voice_channel = ctx.author.voice.channel if ctx.author.voice else None if not voice_channel: await ctx.send("你得先加入一个语音频道!") return # 获取或创建语音客户端 voice_client = server.voice_client if not voice_client: voice_client = await voice_channel.connect() # 如果机器人在其他频道,自动切换到用户所在频道 elif voice_client.channel != voice_channel: await voice_client.move_to(voice_channel) # 创建并启动播放 player = await YTDLSource.from_url(url, loop=client.loop) players[server.id] = player voice_client.play(player) await ctx.send(f"正在播放: {player.title}")
关键修改点说明
- 修复属性拼写:将
ctx.guild.voice_clientn(server)改为server.voice_client,直接访问Guild的语音客户端属性 - 替换废弃方法:用自定义的
YTDLSource类替代已移除的create_ytdl_player,适配新版本discord.py - 增加语音连接校验:先检查用户是否在语音频道,再判断机器人连接状态,未连接则自动加入用户所在频道
- 更新播放逻辑:使用
voice_client.play()方法启动播放,替代旧的player.start()
内容的提问来源于stack exchange,提问作者Alice
相关产品推荐
相关产品推荐

