【问题标题】:Discord.py rewrite - what is the source for YoutubeDL to play music?Discord.py 重写 - YoutubeDL 播放音乐的来源是什么?
【发布时间】:2019-09-25 14:55:19
【问题描述】:

正如文档here 中所述,我需要使用 play() 命令使用源来播放音乐,我正在尝试使用 YoutubeDL 但我无法弄清楚。

我检查了 rapptz discord.py 基本语音示例,但由于我没有使用面向对象编程,这让我很困惑。我看过的所有地方,他们的例子都是使用 v0.16 discord.py,我不知道如何将这个 player = await voice_client.create_ytdl_player(url) 转换为重写。

我现在的播放功能是这样的:

async def play(ctx, url = None):
...
player = await YTDLSource(url) 
    await ctx.voice_client.play(player)
    await ctx.send("Now playing: " + player.title())

“YTDLSource”是源的占位符。

非常感谢任何帮助,谢谢。

【问题讨论】:

    标签: python-3.x youtube-dl discord.py-rewrite


    【解决方案1】:

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

    查看https://github.com/Rapptz/discord.py/blob/master/examples/basic_voice.py 中的 yt 方法:

    @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))
    

    以及它所依赖的 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)
    

    如果您希望从 youtube 流式传输音频而不是预下载音频,请将 player = await YTDLSource.from_url(url, loop=self.bot.loop) 更改为 player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True)

    pastebin 存档:https://pastebin.com/nEiJ5YrD

    【讨论】:

      【解决方案2】:

      我确信通过重写有更好的方法来做到这一点,但我和你在同一条船上。很长时间都想不通。

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

      加入命令:

      @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")
      

      所有需要导入的(我认为):

      import discord
      import youtube_dl
      import os
      from discord.ext import commands
      from discord.utils import get
      from discord import FFmpegPCMAudio
      from os import system
      

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

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

      就像我之前说的那样,可能有一种允许队列命令的方式来做到这一点,但我现在还不知道这种方式。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2021-02-06
        • 2021-05-05
        • 2021-04-09
        • 1970-01-01
        • 2014-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多