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

时间:2019-05-07 22:19:33

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

如文档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”是源的占位符。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我确信通过重写可以有更好的方法,但是我和你在同一条船上。我无法找出最长的时间。

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

加入命令:

@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(有关于如何安装ffmpeg的youtube教程)

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

就像我之前说过的那样,可能有一种更简便的方法允许执行队列命令,但是到目前为止我还不知道这种方式。

希望这会有所帮助!

答案 1 :(得分:0)

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