【问题标题】:Discord music bot joined the voice channel but plays no sound Discord.pyDiscord 音乐机器人加入语音频道但不播放声音 Discord.py
【发布时间】:2022-01-04 02:53:25
【问题描述】:

我正在尝试创建一个播放音乐的不和谐音乐机器人。并且带有以下代码的机器人根本不播放音乐(但成功加入)。
我认为使用 youtube_dl 提取信息和获取 URL 的代码是正确的。我可以打开它提取的 URL,这是我想要播放的正确歌曲。 但是当它运行到这条线时:
self.voice.play(discord.FFmpegPCMAudio(yt_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
机器人似乎卡在那里并且根本没有声音。

顺便说一句,当我只执行join 命令时,机器人也会显示语音活动,所以这也很奇怪。
这是我与此相关的所有代码:

    @commands.command(description="Join the channel", aliases=['j'])
    async def join(self, ctx):
        if ctx.message.author.voice is not None:
            try:
                channel = ctx.message.author.voice.channel
                self.voice = ctx.guild.voice_client

                if self.voice and self.voice.is_connected():  # User in voice channel & Bot also in voice channel somewhere else maybe.
                    await self.voice.move_to(channel)
                else:
                    self.voice = await channel.connect()

                await ctx.send(f"Joined {channel}.")


            except:
                await ctx.send("Failed to join the channel with unexpected error.")


        else:
            await ctx.send("You must join a voice channel first.")

    # search function
    def yt_search(self, keywords):
        with YoutubeDL(self.YDL_OPTIONS) as ydl:
            try:
                info = ydl.extract_info(f"ytsearch:{keywords}", download=False)['entries'][0]
                print(info)
                # print(info['entries'][0])

                # return 251/250/249/140/171 otherwise the first one
                all_options = info['formats']  # all dicts

                # create a dict for high quality url if available
                high_quality_dict = {}

                for option in all_options:
                    print(option)
                    if option['format_id'] == '249' or option['format_id'] == '250' or option['format_id'] == '251' or \
                        option['format_id'] == '140' or option['format_id'] == '171':
                        high_quality_dict[option['format_id']] = option['url']  # throw it into dictionary

                # check the high quality one
                if '251' in high_quality_dict:
                    return high_quality_dict['251']
                elif '250' in high_quality_dict:
                    return high_quality_dict['250']
                elif '249' in high_quality_dict:
                    return high_quality_dict['249']
                elif '140' in high_quality_dict:
                    return high_quality_dict['140']
                elif '171' in high_quality_dict:
                    return high_quality_dict['171']
                else:  # if no high quality
                    return all_options[0]['url']

            except:
                return False

    # play next func
    def play_next(self):
        with open('resources/server_playlist.json', 'r') as f:
            current_playlist = json.load(f)

            current_playlist[self.str_guild_id].pop(0)  # pop the one just played

        if len(current_playlist[self.str_guild_id]) > 0:
            yt_url = current_playlist[self.str_guild_id][0]

            self.voice.play(discord.FFmpegPCMAudio(yt_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
        else:
            self.is_playing = False

    # play command
    @commands.command(description="Play music from youtube", aliases=['p', 'listen'])
    async def play(self, ctx, *, args):
        search_words = " ".join(args)

        if ctx.author.voice is not None:
            song = self.yt_search(search_words)

            if song is False:  # failed to achieve url in the search step
                await ctx.send("Failed to load the song. Unexpected error.")
            else:
                self.str_guild_id = str(ctx.guild.id)

                with open('resources/server_playlist.json', 'r') as f:
                    server_playlist = json.load(f)

                # check whether server_id is in the json
                if self.str_guild_id not in server_playlist:
                    server_playlist[self.str_guild_id] = list()

                # add the songs into queue
                server_playlist[self.str_guild_id].append(song)

                with open('resources/server_playlist.json', 'w') as f:
                    json.dump(server_playlist, f, indent=4)

                # check if the bot currently is playing then connect to vc.
                if self.is_playing is False:
                    yt_url = server_playlist[self.str_guild_id][0]
                    print(yt_url)

                    # join voice channel
                    self.voice = ctx.guild.voice_client
                    self.channel = ctx.author.voice.channel
                    if self.voice and self.voice.is_connected():  # User in voice channel & Bot also in voice channel somewhere else maybe.
                        await self.voice.move_to(self.channel)
                    else:
                        self.voice = await self.channel.connect()

                    self.is_playing = True

                    print("before playing")

                    # play the music (**Having Problem!!!**)
                    self.voice.play(discord.FFmpegPCMAudio(yt_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
                    # self.voice.is_playing()

        else:
            await ctx.send(f"{ctx.author.name}: Please join a voice channel first!")

【问题讨论】:

    标签: python-3.x discord discord.py


    【解决方案1】:

    在从 discord.py discord 服务器询问人们之后,我应该包括为 windows 安装的 ffmpeg,尽管我设置了download=False
    而且我还需要在self.voice.play 代码行中添加executable=<ffmpeg path>。 (我的路径是 C:/ffmpeg/ffmpeg.exe)


    所以,应该是self.voice.play(discord.FFmpegPCMAudio(executable="C:/ffmpeg/ffmpeg.exe", source=yt_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2021-05-05
      • 2022-07-10
      • 2020-09-05
      • 2020-07-16
      • 2021-05-27
      • 2021-05-24
      • 2019-01-11
      • 2021-12-08
      相关资源
      最近更新 更多