无法为 Discord 机器人分配其已连接的语音通道

问题描述 投票:0回答:1

我正在尝试学习如何使用 Discord.py 编写机器人代码,并且正在关注 Dasma tech 的 YouTube 教程,了解如何创建音乐机器人。

我已经到了机器人可以加入发送命令的人的语音通道的地步,但是,在分配字典“self.vc[id] =等待channel.connect()”时,它没有被分配。

我已经检查了多次代码,与Dasma Tech的相同,并且运行代码时没有任何错误。

我正在 Raspberry pi 5 上运行代码,如果这有任何帮助的话。

What is outputted to terminal after using the command in discord while connected to a voice channel

在测试问题时,我在调用函数 join_VC 之前和之后添加了一个打印,第一个打印工作正常,但之后的打印不起作用,我不明白为什么。分配后 join_VC 中的打印和调用 join_VC 后的 ctx.send 也没有输出。

我相信分配 self.vc[id] 的问题是阻止机器人在使用离开命令时离开语音通道,因为它不知道它连接到什么,因为 self.vc[ 的默认值id] 为无。

代码:

导入不和谐 从discord_components导入选择,选择选项,按钮 导入不和谐.ext 从discord.ext导入命令 导入异步 从 asyncio 导入 run_coroutine_threadsafe 从 urllib 导入解析,请求 进口重新 导入 json 导入操作系统 从 youtube_dl 导入 YoutubeDL

类 music_cog(commands.Cog): def init(自我,机器人): self.bot = 机器人

    self.is_playing = {}
    self.is_paused = {}
    self.musicQueue = {}
    self.queueIndex = {}
    
    self.YTDL_OPTIONS = {'format': 'bestaudio', 'nonplaylist': 'True'}
    self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
    
    self.embedBlue = 0x2c76dd
    self.embedRed = 0xdf1141
    self.embedGreen = 0x0eaa51
    
    self.vc = {}
    
@commands.Cog.listener()
async def on_ready(self):
    for guild in self.bot.guilds:
        id = int(guild.id)
        self.musicQueue[id] = []
        self.queueIndex[id] = 0
        self.vc[id] = None
        self.is_paused[id] = self.is_playing[id] = False

@commands.Cog.listener()
async def on_voice_state_update(self, member, before, after):
    id = int(member.guild.id)
    if member.id != self.bot.user.id and before.channel != None and after.channel != before.channel:
        remainingChannelMembers = before.channel.members
        if len(remainingChannelMembers) == 1 and remainingChannelMembers[0].id == self.bot.user.id and self.vc[id].is_connected():
            self.is_playing[id] = self.is_paused[id] = False
            self.musicQueue[id] = []
            self.queueIndex[id] = 0
            await self.vc[id].disconnect()
    
def now_playing_embed(self, ctx, song):
    title = song['title']
    link = song['link']
    thumbnail = song['thumbnail']
    author = ctx.author
    avatar = author.avatar_url
    
    embed = discord.Embed(
        title = "Now Playing",
        description=f'[{title}]({link})',
        colour = self.embedGreen
    )
    embed.set_thumbnail(url=thumbnail)
    embed.set_footer(text=f'Song added by: {str(author)}', icon_url=avatar)
    return embed
        
async def join_VC(self, ctx, channel):
    id = int(ctx.guild.id)
    if self.vc[id] == None or not self.vc[id].is_connected():
        self.vc[id] = await channel.connect()
        print("It is: ", self.vc[id], " in join_vc")

        if self.vc[id] == None:
            await ctx.send("Could not connect to the voice channel ")
            return None
    else:
        await self.vc[id].move_to(channel)
        print(self.vc[id])
        
        
def search_YT(self, search):
    queryString = parse.urlencode({'search_query': search})
    htmContent = request.urlopen('http://www.youtube.com/results?' + queryString)
    searchResults = re.findall('/watch\?v=(.{11})', htmContent.read().decode())
    return searchResults[0:10]
    
def extract_YT(self, url):
    with YoutubeDL(self.YTDL_OPTIONS) as ydl:
        try:
            info = ydl.extract_info(url, download=False)
        except:
            return False
        
    return {
        'link': 'https://www.youtube.com/watch?v=' + url,
        'thumbnail': 'https://i.ytimg.com/vi/' + url + '/hqdefault.jpg?sqp=-oaymwEcCOADEI4CSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD5ul4xKN-IUfez6KIW_j5y70mlig',
        'source': info['formats'][0]['url'],
        'title': info['title']
    }
    
def play_next(self, ctx):
    id = int(ctx.guild.id)
    if not self.is_playing[id]:
        return
    if self.queueIndex[id] + 1 < len(self.musicQueue[id]):
        self.i_playing[id] = True
        self.queueIndex[id] += 1
        
        song = self.musicQueue[id][self.queueIndex[id]][0]
        message = self.now_playing_embed(ctx, song)
        coro = ctx.send(embed=message)
        fut = run_coroutine_threadsafe(coro, self.bot.loop)
        try:
            fut.result()
        except:
            pass
            
        self.vc[id].play(discord.FFmegPCMAudio(
            song['source'], ** self.FFMPEG_OPTIONS), after=lambda e: self.play_next(ctx))
    else:
        self.queueIndex[id] += 1
        self.is_playing[id] = False

async def play_music(self, ctx):
    id = int(ctx.guild.id)
    if self.queueIndex[id] < len(self.musicQueue[id]):
        self.is_playing[id] = True
        self.is_paused[id] = False
        
        await self.join_VC(ctx, self.musicQueue[id][self.queueIndex[id]][1])
        
        song = self.musicQueue[id][self.queueIndex[id]][0]
        message = self.now_playing_embed(ctx, song)
        await ctx.send(embed=message)
        
        self.vc[id].play(discord.FFmpegPCMAudio(
            song['source'], **self.FFMPEG_OPTIONS), after=lambda e: self.play_next(ctx))
    else:
        await ctx.send("There are no songs in queue to be played")
        self.queueIndex[id] += 1
        self.is_playing = False
    
@ commands.command(
    name="join",
    aliases=["j","jion"],
    help=""
)
async def join(self, ctx):
    id = int(ctx.guild.id)
    if ctx.author.voice:
        userChannel = ctx.message.author.voice.channel
        print("Before assignment self.vc[id] = ", self.vc[id])
        await self.join_VC(ctx, userChannel)
        print("After assignment self.vc[id] = ", self.vc[id])
        await ctx.send(f'Rhythmus has joined {userChannel}')

    else:
        await ctx.send("You need to be in a voice channel")
    
@ commands.command(
    name="leave",
    aliases=["l","laeve"],
    help=""
)
async def leave(self, ctx):
    id = int(ctx.guild.id)
    self.is_playing[id] = self.is_paused[id] = False
    self.musicQueue[id] = []
    self.queueIndex[id] = 0
    if self.vc[id] != None:
        await ctx.send("Rhythmus has left the voice channel")
        await self.vc[id].disconnect()
discord discord.py
1个回答
0
投票

这有几个问题

问题一

您分配的方式:

self.vc[id] = await channel.connect()

channel.connect()
放入您稍后将使用的词典中。但是,
channel.connect()
返回另一个类,该类不返回 VC 的会话 ID(我认为这就是您想要获取的)。相反,它返回 VoiceClient。

来自 docs 的返回类型

与语音服务器完全连接的语音客户端。

如果您查看返回类型,您会看到它返回一个

discord.VoiceProtocol
。这意味着它将是一个类,而不是实际的 VC ID 或会话 ID(我假设您想要)。

问题二

我意识到以下是错误的,因为它只是格式正确......

这里的范围是错误的。您多次使用

self
,但它不在同一类中。这意味着它将始终返回
None
,因为它无法被引用。

© www.soinside.com 2019 - 2024. All rights reserved.