Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Discord.py重写-YoutubeDL播放音乐的来源是什么?_Python 3.x_Youtube Dl_Discord.py Rewrite - Fatal编程技术网

Python 3.x Discord.py重写-YoutubeDL播放音乐的来源是什么?

Python 3.x Discord.py重写-YoutubeDL播放音乐的来源是什么?,python-3.x,youtube-dl,discord.py-rewrite,Python 3.x,Youtube Dl,Discord.py Rewrite,正如文档中提到的,我需要使用play()命令使用一个源来播放音乐,我正在尝试使用YoutubeDL,但我无法找到它 我已经检查了rapptz discord.py基本语音示例,但由于我没有使用面向对象编程,这让我非常困惑。我所看到的每一个地方,他们的例子都是使用v0.16 discord.py,我不知道如何将这个player=wait voice\u客户端转换为重写 目前我的播放功能如下所示: async def play(ctx, url = None): ... player = await

正如文档中提到的,我需要使用play()命令使用一个源来播放音乐,我正在尝试使用YoutubeDL,但我无法找到它

我已经检查了rapptz discord.py基本语音示例,但由于我没有使用面向对象编程,这让我非常困惑。我所看到的每一个地方,他们的例子都是使用v0.16 discord.py,我不知道如何将这个
player=wait voice\u客户端转换为重写

目前我的播放功能如下所示:

async def play(ctx, url = None):
...
player = await YTDLSource(url) 
    await ctx.voice_client.play(player)
    await ctx.send("Now playing: " + player.title())
“YTDLSource”是源的占位符


非常感谢您的帮助。

我相信有更好的重写方法,但我和您是同舟共济的。我花了很长时间才弄明白

在浏览了youtube dl文档和重写文档之后,这是我能想到的最好的了。请记住,我不知道这是否适用于队列系统(可能不适用)。另外,我不知道这是一个bug还是我做错了什么,当bot加入时,然后你使用play命令,它不会输出音乐,但是如果bot离开,然后再次加入,音乐就会播放。为了解决这个问题,我让join命令join、leave和join

联接命令:

@bot.command(pass_context=True, brief="Makes the bot join your channel", aliases=['j', 'jo'])
async def join(ctx):
    channel = ctx.message.author.voice.channel
    if not channel:
        await ctx.send("You are not connected to a voice channel")
        return
    voice = get(bot.voice_clients, guild=ctx.guild)
    if voice and voice.is_connected():
        await voice.move_to(channel)
    else:
        voice = await channel.connect()
    await voice.disconnect()
    if voice and voice.is_connected():
        await voice.move_to(channel)
    else:
        voice = await channel.connect()
    await ctx.send(f"Joined {channel}")
播放命令:

@bot.command(pass_context=True, brief="This will play a song 'play [url]'", aliases=['pl'])
async def play(ctx, url: str):
    song_there = os.path.isfile("song.mp3")
    try:
        if song_there:
            os.remove("song.mp3")
    except PermissionError:
        await ctx.send("Wait for the current playing music end or use the 'stop' command")
        return
    await ctx.send("Getting everything ready, playing audio soon")
    print("Someone wants to play music let me get that ready for them...")
    voice = get(bot.voice_clients, guild=ctx.guild)
    ydl_opts = {
        'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
    }
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download([url])
    for file in os.listdir("./"):
        if file.endswith(".mp3"):
            os.rename(file, 'song.mp3')
    voice.play(discord.FFmpegPCMAudio("song.mp3"))
    voice.volume = 100
    voice.is_playing()
离开命令:

@bot.command(pass_context=True, brief="Makes the bot leave your channel", aliases=['l', 'le', 'lea'])
async def leave(ctx):
    channel = ctx.message.author.voice.channel
    voice = get(bot.voice_clients, guild=ctx.guild)
    if voice and voice.is_connected():
        await voice.disconnect()
        await ctx.send(f"Left {channel}")
    else:
        await ctx.send("Don't think I am in a voice channel")
所有需要导入的内容(我认为):

您可能还需要从他们的网站下载ffmpeg(youtube上有关于如何下载和安装ffmpeg的教程)

使用带有youtube url('/Play www.youtube.com')的Play命令行,它将首先查找“song.mp3”,并删除它(如果有),下载新歌并将其重命名为“song.mp3”,然后播放mp3文件。mp3文件将放在与bot.py相同的目录中

正如我之前所说,可能有一种更好的方法来实现这一点,允许使用队列命令,但我现在还不知道这种方法


希望这有帮助

discord文档现在提供了一个完整的示例,说明如何制作一个实现ytdl的语音机器人

查看以下内容中的yt方法:

以及它所依赖的YTDLSource类:

ytdl_format_options = {
    'format': 'bestaudio/best',
    'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
    'restrictfilenames': True,
    'noplaylist': True,
    'nocheckcertificate': True,
    'ignoreerrors': False,
    'logtostderr': False,
    'quiet': True,
    'no_warnings': True,
    'default_search': 'auto',
    'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}

ffmpeg_options = {
    'options': '-vn'
}

ytdl = youtube_dl.YoutubeDL(ytdl_format_options)

class YTDLSource(discord.PCMVolumeTransformer):
    def __init__(self, source, *, data, volume=0.5):
        super().__init__(source, volume)

        self.data = data

        self.title = data.get('title')
        self.url = data.get('url')

    @classmethod
    async def from_url(cls, url, *, loop=None, stream=False):
        loop = loop or asyncio.get_event_loop()
        data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))

        if 'entries' in data:
            # take first item from a playlist
            data = data['entries'][0]

        filename = data['url'] if stream else ytdl.prepare_filename(data)
        return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
player=await YTDLSource.从\u url(url,loop=self.bot.loop)
更改为
player=await YTDLSource.从\u url(url,loop=self.bot.loop,stream=True)
如果您希望从youtube流式播放音频而不是预下载音频

pastebin存档:

@commands.command()
async def yt(self, ctx, *, url):
    """Plays from a url (almost anything youtube_dl supports)"""

    async with ctx.typing():
        player = await YTDLSource.from_url(url, loop=self.bot.loop)
        ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None)

    await ctx.send('Now playing: {}'.format(player.title))
ytdl_format_options = {
    'format': 'bestaudio/best',
    'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
    'restrictfilenames': True,
    'noplaylist': True,
    'nocheckcertificate': True,
    'ignoreerrors': False,
    'logtostderr': False,
    'quiet': True,
    'no_warnings': True,
    'default_search': 'auto',
    'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}

ffmpeg_options = {
    'options': '-vn'
}

ytdl = youtube_dl.YoutubeDL(ytdl_format_options)

class YTDLSource(discord.PCMVolumeTransformer):
    def __init__(self, source, *, data, volume=0.5):
        super().__init__(source, volume)

        self.data = data

        self.title = data.get('title')
        self.url = data.get('url')

    @classmethod
    async def from_url(cls, url, *, loop=None, stream=False):
        loop = loop or asyncio.get_event_loop()
        data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))

        if 'entries' in data:
            # take first item from a playlist
            data = data['entries'][0]

        filename = data['url'] if stream else ytdl.prepare_filename(data)
        return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)