使用Pycord开发音频录制Bot时遇sink参数缺失错误求助
问题分析与解决方案
错误根源
你遇到的MissingRequiredArgument: sink is a required argument that is missing错误,本质有两个核心问题:
- 调用
.start命令时未指定音频格式参数(比如mp3/wav); - 代码本身存在几个关键问题:前缀命令错误使用了斜杠命令专用的
ApplicationContext、自定义Enum无法被Pycord命令转换器识别、未开启语音相关Intents。
修正后的完整代码
import discord from enum import Enum import os from discord.ext import commands # 开启必要的Intents,包括语音状态和消息内容 intents = discord.Intents.default() intents.message_content = True intents.voice_states = True # 必须开启,否则无法获取用户语音频道信息 bot = commands.Bot(command_prefix=".", case_insensitive=True, intents=intents) connections = {} # 重新定义Sinks Enum,存储Sink类而非直接实例化 class Sinks(Enum): mp3 = discord.sinks.MP3Sink wav = discord.sinks.WaveSink pcm = discord.sinks.PCMSink ogg = discord.sinks.OGGSink mka = discord.sinks.MKASink mkv = discord.sinks.MKVSink mp4 = discord.sinks.MP4Sink m4a = discord.sinks.M4ASink async def finished_callback(sink, channel: discord.TextChannel, *args): recorded_users = [f"<@{user_id}>" for user_id, audio in sink.audio_data.items()] await sink.vc.disconnect() files = [ discord.File(audio.file, f"{user_id}.{sink.encoding}") for user_id, audio in sink.audio_data.items() ] await channel.send( f"录制完成!已录制以下用户的音频:{', '.join(recorded_users)}", files=files ) @bot.command() async def start(ctx: commands.Context, sink_type: str): """开始录制语音,需指定格式,例如:.start mp3""" # 检查用户是否在语音频道 if not ctx.author.voice: return await ctx.reply("你现在不在语音频道里!") # 验证传入的格式是否合法 try: sink_cls = getattr(Sinks, sink_type.lower()).value except AttributeError: valid_formats = [member.name for member in Sinks] return await ctx.reply(f"不支持的格式!可选格式:{', '.join(valid_formats)}") # 连接到用户所在的语音频道 vc = await ctx.author.voice.channel.connect() connections[ctx.guild.id] = vc # 实例化Sink并开始录制 sink = sink_cls() vc.start_recording( sink, finished_callback, ctx.channel ) await ctx.reply(f"已开始录制,格式为{sink_type}!") @bot.command() async def stop(ctx: commands.Context): """停止当前录制""" if ctx.guild.id in connections: vc = connections[ctx.guild.id] vc.stop_recording() del connections[ctx.guild.id] await ctx.reply("已停止录制,正在处理音频...") else: await ctx.reply("当前服务器没有正在进行的录制!") @bot.event async def on_ready(): print(f"Bot已上线:{bot.user}") bot.run(os.getenv('TOKEN'))
关键修改说明
- 修正上下文类:将
ApplicationContext替换为commands.Context,前缀命令必须使用该上下文类,才能正常调用ctx.reply、ctx.author.voice等方法; - 重构Enum定义:原Enum直接实例化Sink对象,改为存储Sink类,避免复用实例导致的异常,同时方便参数验证;
- 优化参数处理:将
sink: Sinks改为sink_type: str,手动验证格式合法性,解决Pycord转换器无法识别自定义Enum的问题; - 开启语音Intents:添加
intents.voice_states = True,这是Bot获取用户语音状态的必要权限,缺失会导致ctx.author.voice返回None; - 修复stop命令逻辑:将
await ctx.delete()改为回复提示,避免因用户消息已删除导致的报错; - 增强用户提示:添加格式验证反馈,让用户清楚知道支持的音频格式。
使用方法
- 开始录制:
.start mp3(可替换为wav、ogg等支持的格式) - 停止录制:
.stop
内容的提问来源于stack exchange,提问作者Shweta K
相关产品推荐
相关产品推荐

