You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord音乐机器人报错:缺少必填关键字参数query

Discord音乐机器人query参数识别失败问题

报错信息

File "C:\Users\pc\Desktop\Bot\Mbot\Bot.py", line 77, in play
await play_music(last_item)

^^^^^^^^^^^^^^^^^^^^^

TypeError: play_music() missing 1 required keyword-only argument: 'query'

问题描述

开发Discord音乐机器人时,输入play命令并传入YouTube链接,链接会被加入队列,但机器人无法识别传入的链接,调用play_music时始终报缺少query参数的错误,即使把调用参数从last_item换成query,错误依然存在。预期逻辑是链接加入队列后立即用该链接播放音乐。

相关代码

import discord
import os
from discord.ext import commands
from discord.ui import Button,View
from discord.utils import get
import yt_dlp
import youtube_dl

intents = discord.Intents().all()
intents.message_content = True
intents.voice_states = True
intents.presences = True
bot = commands.Bot(command_prefix = '!!', intents=intents)


queue_list = []

async def play_music(ctx, *, query):
        ydl_opts = {
            'format': 'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
        }
        ffmpeg_options = {
            'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
            'options': '-vn',
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(query, download=False)
            url2 = info['formats'][0]['url']
        
            voice_client.play(discord.FFmpegPCMAudio(url2, **ffmpeg_options))
@bot.command()
async def join(ctx):
    await ctx.author.voice.channel.connect()

@bot.command()
async def play(ctx, *, query):
    queue_list.append(query)
    last_item = queue_list[-1]
    voice_client = ctx.voice_client
    voice_channel = ctx.author.voice.channel
    if voice_channel is None:
        await ctx.send("text1")
    elif 'youtube.com' in query or 'youtu.be' in query:
        await play_music(last_item) 
    else:
        await ctx.send('text2')

bot.run(os.getenv('TOKEN'))

解决方案

问题出在两个核心点:

  1. 参数传递不完整:play_music定义时第一个参数是ctx,但调用时只传了last_item,遗漏了ctx参数。同时函数用*, query声明了关键字-only参数,调用时需确保参数传递正确。
    修正调用代码:

    await play_music(ctx, query=last_item)
    # 或者按位置传递
    await play_music(ctx, last_item)
    
  2. voice_client未定义:play_music函数内直接使用voice_client,但该变量仅在play命令中定义,需通过ctx获取或作为参数传入。推荐通过ctx获取:

    async def play_music(ctx, *, query):
            ydl_opts = {
                'format': 'bestaudio/best',
                'postprocessors': [{
                    'key': 'FFmpegExtractAudio',
                    'preferredcodec': 'mp3',
                    'preferredquality': '192',
                }],
            }
            ffmpeg_options = {
                'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
                'options': '-vn',
            }
            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                info = ydl.extract_info(query, download=False)
                url2 = info['formats'][0]['url']
            
            # 通过ctx获取语音客户端并判断连接状态
            voice_client = ctx.voice_client
            if voice_client and voice_client.is_connected():
                voice_client.play(discord.FFmpegPCMAudio(url2, **ffmpeg_options))
            else:
                await ctx.send("机器人未连接到语音频道!")
    

额外优化:youtube_dl已停止维护,建议移除该导入,统一使用yt_dlp,将代码中youtube_dl替换为yt_dlp即可。

内容的提问来源于stack exchange,提问作者The Kjilpo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:07:31