Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Дискорд Бот на Python

ARTYK official Ученик (190), на голосовании 1 год назад
Добрый вечер! Я все еще разрабатываю своего бота для Дискорда, в этот раз решил добавить проигрывание музыки. В первый раз все получилось, но во второй начало выдавать ошибку. Сидел 4 часа но так и не решил проблему...
Вот ошибка:
File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 490, in wait_for
return fut.result()
^^^^^^^^^^^^
File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\client_ws.py", line 229, in receive
msg = await self._ reader.read ()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\streams.py", line 657, in read
return await super().read()
^^^^^^^^^^^^^^^^^^^^


"C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\gateway.py", line 1003, in poll_event
msg = await asyncio.wait_for(self.ws.receive(), timeout=30.0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Вот мой код:
@bot.command()
async def play(ctx, url : str):
song_there = os.path.isfile('song.mp3')

try:
if song_there:
os.remove('song.mp3')
print('[log] Старая песня съедена Камилем!')
except PermissionError:
print('[log] Старую песня съесть не удалось :(')

await ctx.send('Ща все будет')

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:
print('[log] Загружаю музыку...')
ydl.download ([url])

for file in os.listdir('./'):
if file.endswith('.mp3'):
name = file
print(f'[log] Переименовываю файл: {file}')
os.rename(file, 'song.mp3')

voice.play(discord.FFmpegPCMAudio('song.mp3'))
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 0.07

song_name = name.rsplit('-', 2)
await ctx.send(f'Врубил песню {song_name[0]}')


Буду очень благодарен если вы подскажете?
Голосование за лучший ответ
Жирный Жир Гуру (3948) 1 год назад
 import os 
import youtube_dl
import discord
from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.command()
async def play(ctx, url: str):
song_there = os.path.isfile('song.mp3')

try:
if song_there:
os.remove('song.mp3')
print('[log] Старая песня съедена Камилем!')
except PermissionError:
print('[log] Старую песню съесть не удалось :(')

await ctx.send('Ща все будет')

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:
print('[log] Загружаю музыку...')
info = ydl.extract_info(url, download=False)
url2 = info['formats'][0]['url']

if not voice.is_playing():
voice.play(discord.FFmpegPCMAudio(url2), after=lambda e: print('done', e))
voice.is_playing()
else:
await ctx.send('Уже воспроизводится музыка')

song_name = info['title']
await ctx.send(f'Врубил песню {song_name}')

bot.run('YOUR_BOT_TOKEN')
Помимо исправления асинхронных операций, внесены следующие изменения:

Используется библиотека youtube_dl для получения URL музыки, таким образом, вы избегаете синхронной загрузки музыки.

При проверке, воспроизводится ли уже музыка, используется voice.is _playing().

Добавлено ожидание завершения воспроизведения для печати "done" после завершения воспроизведения.

Убедитесь, что вы подставили свой токен бота ( bot.run ('YOUR_BOT_TOKEN')) и что у вас правильно настроена ваша среда выполнения Python с асинхронной библиотекой Discord.
ARTYK officialУченик (190) 1 год назад
Спасибо большое, все стало нормально работать!?

Только вот при воспроизведении песня на половине выключается, не могли бы пожалуйста подсказать что делать в таком случае??
Жирный Жир Гуру (3948) ARTYK official, Увеличьте таймаут: Добавьте таймаут для ожидания завершения воспроизведения, чтобы предотвратить преждевременное завершение воспроизведения песни. Вы можете сделать это, добавив await voice.disconnect() в блок after:
 voice.play(discord.FFmpegPCMAudio(url2), after=lambda e: print('done', e)) 
await voice.disconnect() 
 
Обновите библиотеки: Убедитесь, что у вас установлены последние версии библиотек discord.py и youtube_dl. Вы можете обновить их с помощью pip:
 pip install -U discord.py youtube-dl 
 
Логирование ошибок: Добавьте логирование ошибок, чтобы получить более подробную информацию о проблеме. Вы можете использовать try...except для ловли ошибок и вывода их в консоль. Эти шаги могут помочь вам выявить и решить проблему с воспроизведением песни.
ARTYK officialУченик (190) 1 год назад
Блин, бот теперь отключается при включении песни и не проигрывает ее. Библиотеки обновил. При выключении песни выдает ошибку discord.player: ffmpeg process 17084 successfully terminated with return code of 0.
Похожие вопросы