очереди воспроизведения в discord.py
Пилю бота для воспроизведения 30 гб треков на сервере, по команде + начало пригрывания, — стоп, skip следующий. Тут все ясно, вопрос вот в чем, воспроизведение происходит следующим образом через либу :
# подключение channel = message.author.voice.channel voice = await channel.connect() # воспроизведение voice.play(discord.FFmpegPCMAudio('test.mp3'))
не могу въехать как следить за воспроизведением по очереди
noname_user ★★★
04.07.19 16:52:56 MSK
Как добавить список треков
Делаю музыкального бота, столкнулся с проблемой добавления музыки в список и последующем воспроизведении. Чтобы можно было во время проигрывания видео в боте ещё раз прописать команду play и поставить в очередь видео, которое воспроизведётся после окончания предыдущего. Мой код:
YDL_OPTIONS = FFMPEG_OPTIONS = client = commands.Bot( command_prefix ='!', intents = intents) #Музыка @client.command() async def join(ctx): await ctx.message.author.voice.channel.connect() @client.command() async def leave(ctx): await ctx.guild.voice_client.disconnect() @client.command() async def play(ctx, *, arg): if not ctx.message.author.voice: await ctx.send('Ты не в голосовом канале') return try: voice = discord.utils.get(client.voice_clients, guild=ctx.guild) with YoutubeDL(YDL_OPTIONS) as ydl: if 'https://' in arg: info = ydl.extract_info(arg, download=False) else: info = ydl.extract_info(f"ytsearch:", download=False)['entries'][0] url = info['formats'][0]['url'] voice.play(discord.FFmpegPCMAudio(executable ="ffmpeg\\ffmpeg.exe", source=url, **FFMPEG_OPTIONS)) info = str(info) await ctx.send('https://www.youtube.com/watch?v='+info[8:19]) except: await ctx.message.author.voice.channel.connect() voice = discord.utils.get(client.voice_clients, guild=ctx.guild) with YoutubeDL(YDL_OPTIONS) as ydl: if 'https://' in arg: info = ydl.extract_info(arg, download=False) else: info = ydl.extract_info(f"ytsearch:", download=False)['entries'][0] url = info['formats'][0]['url'] voice.play(discord.FFmpegPCMAudio(executable="ffmpeg\\ffmpeg.exe", source=url, **FFMPEG_OPTIONS)) info = str(info) await ctx.send('https://www.youtube.com/watch?v=' + info[8:19])
Бот дискорд проигрывает музыку не полностью. В чем проблема и как решить?
бот, написанный на Python, проигрывает музыку с youtube определенное кол-во времени.
Я решил записать время проигрывания. Запустив один и тот же трек два раза, он проиграл его 48 секунд оба раза. Сам трек длиной 2:28. Дальше, я решил запустить трек другой длиной (4:03), он его проиграл 2:14. Исходя из этих опытов, могу сделать вывод, что проблема либо в коде, либо в скорости моего интернета. Нужна помощь.
Вот код: (не обращайте внимания на лишние библиотеки, это не весь код:D)
import re import urllib.request import asyncio from asyncio import sleep import yt_dlp import discord from discord.ext import commands YDL_OPTIONS = config = < 'token': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'prefix': '!', >@bot.command() async def play(ctx, arg): voice_channel = ctx.author.voice.channel if ctx.voice_client is None: await voice_channel.connect() if ctx.voice_client.is_playing(): await ctx.send("something is currently playing. ") return with yt_dlp.YoutubeDL(YDL_OPTIONS) as ydl: secret = arg info = ydl.extract_info(secret, download=False) url2 = info['url'] print(url2) source = discord.FFmpegPCMAudio(url2) vc = ctx.voice_client vc.play(source) bot.run(config['token'])
- Вопрос задан 04 апр. 2023
- 44 просмотра
1 комментарий
Простой 1 комментарий
Общее
Общие вопросы, касающиеся использования библиотеки, относятся сюда.
Это содержание было взято непосредственно из документации и унаследованно от discord.py . Скорее всего, в будущем оно будет переписано.
Где я могу найти примеры использования?
Пример кода можно найти в папке примеры.
Как мне установить статус «Играет в»?
Именованный аргумент activity может быть передан в конструкторе commands.Bot или Bot.change_presence , учитывая ссылку Activity объект.
Конструктор может использоваться для статических активностей, в то время как Bot.change_presence может использоваться для обновления активности во время выполнения.
Настоятельно не рекомендуется использовать Bot.change_presence или вызовы API в on_ready , поскольку это событие может вызываться много раз во время выполнения, не только один раз. Существует высокая вероятность отключения, если присутствие будет изменено сразу после подключения.
Тип статуса можно задать с помощью ActivityType . В целях оптимизации памяти некоторые действия предлагаются в уменьшенных версиях:
Собрав обе эти части информации вместе, вы получите следующее:
bot = commands.Bot(..., activity=disnake.Game(name="игру")) # Или просмотр: activity = disnake.Activity( name="ютуб", type=disnake.ActivityType.watching, ) bot = commands.Bot(..., activity=activity)
Как мне отправить сообщение в определенный канал?
Вы должны получить канал напрямую, а затем вызвать соответствующий метод. Например:
channel = bot.get_channel(12324234183172) await channel.send("привет")
Как мне отправить сообщение в ЛС?
Вы должны получить объект User или Member и вызвать метод send() . Например:
user = bot.get_user(381870129706958858) await user.send("")
Если вы отвечаете на событие, например на on_message , у вас уже есть ссылка на объект User через Message.author :
await message.author.send("")
Как мне получить ID отправленного сообщения?
Метод abc.Messageable.send возвращает ссылку на Message , которое было отправлено. К ID сообщения можно получить доступ через Message.id :
message = await channel.send("хмм…") message_id = message.id
Как мне загрузить изображение?
Чтобы загрузить что-либо в Discord, вы должны использовать объект File .
Объект File принимает 2 параметра, файлоподобный объект (или путь к файлу) и имя файла для передачи в Discord при загрузке.
Если вы хотите загрузить изображение, это так же просто, как:
await channel.send(file=disnake.File("my_file.png"))
Если у вас есть файлоподобный объект, вы можете сделать следующее:
with open("my_file.png", "rb") as fp: await channel.send(file=disnake.File(fp, "new_filename.png"))
Чтобы загрузить несколько файлов, вы можете использовать именованный аргумент files вместо file :
my_files = [ disnake.File("result.zip"), disnake.File("teaser_graph.png"), ] await channel.send(files=my_files)
Если вы хотите загрузить что-то с URL-адреса, вам придется использовать HTTP-запрос с использованием aiohttp , а затем передайте io.BytesIO экземпляр в File вот так:
import io import aiohttp async with aiohttp.ClientSession() as session: async with session.get(my_url) as resp: if resp.status != 200: return await channel.send("Невозможно загрузить файл. ") data = io.BytesIO(await resp.read()) await channel.send(file=disnake.File(data, "cool_image.png"))
Как я могу добавить реакцию на сообщение?
Вы можете использовать метод Message.add_reaction .
Если вы хотите использовать эмодзи в юникоде, вы должны передать допустимую кодовую точку юникода в строке. В вашем коде вы можете написать это несколькими различными способами:
emoji = "\N" # или '\U0001f44d' или '' await message.add_reaction(emoji)
Если вы хотите использовать эмодзи, которые приходят из сообщения, вы уже получаете их кодовые точки в содержимом, не делая ничего особенного. Вы не можете отправить ‘:thumbsup:’ стиль сокращений.
Для пользовательских эмодзи вы должны передать экземпляр Emoji . Вы также можете передать строку , но если вы можете использовать указанный смайлик, вы должны быть в состоянии использовать Bot.get_emoji , чтобы получить смайлик через ID или использовать utils.find или utils.get на Bot.emojis или Guild.emojis .
Имя и ID пользовательского смайлика можно найти в клиенте, добавив слэш к :custom_emoji: . Например, отправка сообщения \:python3: приведет к .
# Если у вас уже есть ID emoji = bot.get_emoji(310177266011340803) await message.add_reaction(emoji) # Нет ID, выполните поиск emoji = disnake.utils.get(guild.emojis, name="LUL") if emoji: await message.add_reaction(emoji) # Если у вас есть имя и ID пользовательского смайлика: emoji = "" await message.add_reaction(emoji)
Как мне пропустить короутайн функции плеера «after»?
Музыкальный проигрыватель библиотеки запускается в отдельном потоке, следовательно, он не выполняется внутри короутайна. Это не означает, что невозможно вызвать короутайн в параметре after . Для этого вы должны передать вызываемый объект, который включает в себя несколько аспектов.
Первое, о чем вы должны знать, — это то, что вызов короутайна не является потокобезопасной операцией. Поскольку технически мы находимся в другом потоке, мы должны проявлять осторожность при вызове потокобезопасных операций, чтобы не допустить сбоев. К счастью для нас, asyncio поставляется с asyncio.run_coroutine_threadsafe функция, которая позволяет нам вызывать короутайн из другого потока.
Однако эта функция возвращает Future , и чтобы действительно вызвать его, мы должны получить его результат. Собрав все это вместе, мы можем сделать следующее:
def my_after(error): coro = some_channel.send("Песня закончена!") fut = asyncio.run_coroutine_threadsafe(coro, bot.loop) try: fut.result() except: # Произошла ошибка при отправке сообщения pass voice.play(disnake.FFmpegPCMAudio(url), after=my_after)
Как мне запустить что-то в фоновом режиме?
Как мне получить конкретную модель?
Есть несколько способов сделать это. Если у вас есть ID конкретной модели, вы можете использовать одну из следующих функций:
Следующее использует HTTP-запрос:
- abc.Messageable.fetch_message
- Bot.fetch_user
- Bot.fetch_guilds
- Bot.fetch_guild
- Bot.fetch_emojis
- Bot.fetch_emoji
- Bot.fetch_member
Если вышеприведенные функции вам не помогают, то использование utils.find или utils.get может быть полезно для поиска конкретных моделей.
# Найдите сервер по названию guild = disnake.utils.get(bot.guilds, name="My Server") # Обязательно проверьте, найден ли он if guild is not None: # Поиск канала по названию channel = disnake.utils.get(guild.text_channels, name="cool-channel")
Как мне сделать веб-запрос?
Чтобы сделать запрос, вы должны использовать неблокирующую библиотеку. Эта библиотека уже использует и требует стороннюю библиотеку для выполнения запросов, aiohttp .
async with aiohttp.ClientSession() as session: async with session.get("http://aws.random.cat/meow") as r: if r.status == 200: js = await r.json()
Смотрите полную документацию по aiohttp для большей информации.
Как мне использовать локальный файл изображения для изображения в эмбеде?
Настройка локального изображения для эмбеда может быть выполнена с помощью аргумента file в методе Embed.set_image . Он принимает File объект.
embed = disnake.Embed() embed.set_image(file=disnake.File("path/to/file.png")) await channel.send(embed=embed)
Существует ли событие для создания записей журнала аудита?
Поскольку Discord не отправляет эту информацию в шлюз, библиотека не может предоставить эту информацию. В настоящее время это ограничение Discord.