0

我用 discord.py 和 youtube-dl 制作的机器人有一个奇怪的问题,当我加载一个小播放列表时,机器人工作得很好,而当我加载一个长播放列表时,比如 100 首歌曲,机器人必须下载它们然后启动它们,我认为用于下载歌曲的时间被视为不活动,然后机器人断开连接,但是它不会从不和谐的频道断开连接,只有代码端断开连接,我该如何解决?

这是我的加入功能:

@commands.command()
async def join(self, ctx):
    if ctx.author.voice is None:
        await ctx.send("Non sei in un canale non so dove andare")
    else:
        voice_channel = ctx.author.voice.channel
        if ctx.voice_client is None:
            await voice_channel.connect()
        else:
            await ctx.voice_client.move_to(voice_channel)
        self.is_connected = True

这是我的播放功能:

@commands.command()
async def play(self, ctx, url):
    if ctx.voice_client is None:
        await self.join(ctx)
    if self.is_connected:
        with youtube_dl.YoutubeDL(self.YDL_OPTIONS) as ydl:
            info = ydl.extract_info(url, download=False)
            #print(info)
        titleartist = ''
        duration = ''
        #print("INFO:  " + str(info))
        if info.get('_type') == 'playlist':
            temp_url = ' '
            for x in info.get('entries'):
                #print("x:  " + str(x))
                temp_url = x['formats'][0]['url']
                if 'title' in x.keys():
                    titleartist = x['title']
                if 'duration' in x.keys():
                    duration = x['duration']
                self.queue.append(temp_url)
                self.songsinfo.append([temp_url, titleartist, duration])
            if not self.playing:
                self.currentsonginfo = self.songsinfo.pop(0)
                temp_song = self.queue.pop(0)
                vc = ctx.voice_client
                source = await discord.FFmpegOpusAudio.from_probe(temp_song, **self.FFMPEG_OPTIONS)
                self.playing = True
                time.sleep(2)
                vc.play(source, after=lambda e: asyncio.run_coroutine_threadsafe(self.next_song(ctx, vc, temp_url), self.client.loop))
        else:
            url2 = info['formats'][0]['url']
            if 'title' in info.keys():
                titleartist = info['title']
            if 'duration' in info.keys():
                duration = info['duration']
            if self.playing:
                self.queue.append(url2)
                self.songsinfo.append([url2, titleartist, duration])
                self.index += 1
                if not self.skipped:
                    await ctx.send("Musica Aggiunta alla Coda")
                else:
                    self.skipped = False
            else:
                self.currentsonginfo = [url2, titleartist, duration]
                vc = ctx.voice_client
                source = await discord.FFmpegOpusAudio.from_probe(url2, **self.FFMPEG_OPTIONS)
                self.playing = True
                time.sleep(2)
                vc.play(source, after=lambda e: asyncio.run_coroutine_threadsafe(self.next_song(ctx, vc, url2), self.client.loop))

这是我得到的错误:

Ignoring exception in command play:
Traceback (most recent call last):
  File "C:\Users\Gian\PycharmProjects\provabot\venv\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "C:\Users\Gian\PycharmProjects\provabot\mymusic.py", line 72, in play
    vc.play(source, after=lambda e: asyncio.run_coroutine_threadsafe(self.next_song(ctx, vc, temp_url), self.client.loop))
  File "C:\Users\Gian\PycharmProjects\provabot\venv\lib\site-packages\discord\voice_client.py", line 555, in play
    raise ClientException('Not connected to voice.')
discord.errors.ClientException: Not connected to voice.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Gian\PycharmProjects\provabot\venv\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\Gian\PycharmProjects\provabot\venv\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\Gian\PycharmProjects\provabot\venv\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ClientException: Not connected to voice.
4

1 回答 1

0

机器人必须全部下载它们然后启动它们

1.不要下载曲目,流式传输原始URL(命令行的参数是--get-url)(您说您正在下载但代码没有提取原始URL?)

2.我注意到 YT-DL 现在似乎变慢了。我使用了一个名为YT-DLP的新库,它比 YT-DL 快得多,而且我能够在 5 秒内解析完整的 200 首歌曲的播放列表。(当然不是下载它们。)

3.与其一次性解析整个播放列表并提取原始 URL,不如仅提取常规 URL,然后当该歌曲从队列中播放时,提取原始 URL,然后播放它。

于 2021-12-19T19:39:43.660 回答