«FFmpeg: ошибка: невозможно перейти к следующей песне в очереди Discord Bot».Python

Программы на Python
Anonymous
«FFmpeg: ошибка: невозможно перейти к следующей песне в очереди Discord Bot».

Сообщение Anonymous »

У меня 3 модуля, но я уверен, что ошибка возникает внутри этого модуля, и вот весь код этого модуля:

Код: Выделить всё

import asyncio
import discord
from discord import FFmpegOpusAudio, Embed
import os

async def handle_help(message):
embed = discord.Embed(
title="Danh sách lệnh cho Bé Mèo",
description="Dưới đây là các lệnh mà chủ nhân có thể bắt Bé Mèo phục vụ:",
color=discord.Color.blue()
)
embed.add_field(name="!play", value="Phát một bài hát từ YouTube.", inline=False)
embed.add_field(name="!pause", value="Tạm dừng bài hát đang phát.", inline=False)
embed.add_field(name="!resume", value="Tiếp tục bài hát đang bị tạm dừng.", inline=False)
embed.add_field(name="!skip", value="Chuyển đến bài hát tiếp theo trong danh sách chờ.", inline=False)
embed.add_field(name="!stop", value="Dừng phát nhạc và cho phép Bé Mèo đi ngủ tiếp.", inline=False)
# Thêm các lệnh khác theo cùng mẫu trên
await message.channel.send(embed=embed)

class Song:
def __init__(self, title, player):
self.title = title  # Lưu trữ tiêu đề bài hát ở đây
self.player = player

# Thêm đối tượng Song vào hàng đợi
def add_song_to_queue(guild_id, queues, song):
queues.setdefault(guild_id, []).append(song)

async def handle_list(message, queues):
log_file_path = "C:\\Bot Music 2\\song_log.txt"
if os.path.exists(log_file_path):
with open(log_file_path, "r", encoding="utf-8") as f:
song_list = f.readlines()

if song_list:
embed = discord.Embed(
title="Danh sách bài hát",
description="Danh sách các bài hát đã phát:",
color=discord.Color.blue()
)

for i, song in enumerate(song_list, start=1):
if i == 1:
song = "- Đang phát: "  + song.strip()
embed.add_field(name=f"Bài hát {i}", value=song, inline=False)

await message.channel.send(embed=embed)
else:
await message.channel.send("Hiện không có dữ liệu trong file log.")
else:
await message.channel.send("File log không tồn tại.")

async def handle_commands(message, client, queues, voice_clients, yt_dl_options, ytdl, ffmpeg_options=None, guild_id=None, data=None):
# Nếu không có ffmpeg_options, sử dụng các thiết lập mặc định
if ffmpeg_options is None:
ffmpeg_options = {
'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn -filter:a "volume=0.25"'
}

# Khởi tạo voice_client
if guild_id is None:
guild_id = message.guild.id

if guild_id in voice_clients:
voice_client = voice_clients[guild_id]
else:
voice_client = None

# Xử lý lệnh !play
if message.content.startswith("!play"):
try:
# Kiểm tra xem người gửi tin nhắn có đang ở trong kênh voice không
voice_channel = message.author.voice.channel
# Kiểm tra xem bot có đang ở trong kênh voice của guild không
if voice_client and voice_client.is_connected():
await voice_client.move_to(voice_channel)
else:
voice_client = await voice_channel.connect()
voice_clients[guild_id] = voice_client
except Exception as e:
print(e)

try:
query = ' '.join(message.content.split()[1:])
if query.startswith('http'):
url = query
else:
query = 'ytsearch:' + query
loop = asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(query, download=False))
if not data:
raise ValueError("Không có dữ liệu trả về từ YouTube.")
url = data['entries'][0]['url']

player = FFmpegOpusAudio(url, **ffmpeg_options)
# Lấy thông tin của bài hát mới đang được yêu cầu
title = data['entries'][0]['title']
duration = data['entries'][0]['duration']
creator = data['entries'][0]['creator'] if 'creator' in data['entries'][0] else "Unknown"
requester = message.author.nick if message.author.nick else message.author.name

# Tạo embed để thông báo thông tin bài hát mới
embed = discord.Embed(
title="Thông tin bài hát mới",
description=f"**Bài hát:** *{title}*\n**Thời lượng:** *{duration}*\n**Tác giả:** *{creator}*\n**Người yêu cầu:** *{requester}*",
color=discord.Color.green()
)
await message.channel.send(embed=embed)

# Sau khi lấy thông tin của bài hát diễn ra, gọi hàm log_song_title với title của bài hát
# Ví dụ:
title = data['entries'][0]['title']
await log_song_title(title)

# Thêm vào danh sách chờ nếu có bài hát đang phát
if voice_client.is_playing():
queues.setdefault(guild_id, []).append(player)
else:
voice_client.play(player)

except Exception as e:
print(e)

if message.content.startswith("!link"):
try:
voice_client = await message.author.voice.channel.connect()
voice_clients[voice_client.guild.id] = voice_client
except Exception as e:
print(e)

try:
url = message.content.split()[1]

loop = asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda:  ytdl.extract_info(url, download=False))

song = data['url']
player = discord.FFmpegOpusAudio(song, **ffmpeg_options)

voice_clients[message.guild.id].play(player)
except Exception as e:
print(e)

# Xử lý lệnh !queue
elif message.content.startswith("!queue"):
queue = queues.get(guild_id, [])
if queue:
await message.channel.send("Danh sách chờ:")
for index, item in enumerate(queue, 1):
await message.channel.send(f"{index}. {item.title}")
else:
await message.channel.send("Không có bài hát nào trong danh sách chờ.")

# Xử lý lệnh !skip
elif message.content.startswith("!skip"):
try:
if voice_client and voice_client.is_playing():
voice_client.stop()
await play_next_song(guild_id, queues, voice_client, skip=True)
await remove_first_line_from_log()
except Exception as e:
print(e)

# Xử lý các lệnh như !pause, !resume, !stop
elif message.content.startswith("!pause"):
try:
if voice_client and voice_client.is_playing():
voice_client.pause()
except Exception as e:
print(e)

elif message.content.startswith("!resume"):
try:
if voice_client and not voice_client.is_playing():
voice_client.resume()
except Exception as e:
print(e)

elif message.content.startswith("!stop"):
try:
if voice_client:
voice_client.stop()
await voice_client.disconnect()
del voice_clients[guild_id]  # Xóa voice_client sau khi dừng
except Exception as e:
print(e)

async def log_song_title(title):
log_file_path = "C:\\Bot Music 2\\song_log.txt"
try:
# Kiểm tra xem tệp tin log đã tồn tại chưa
if not os.path.exists(log_file_path):
# Nếu chưa tồn tại, tạo tệp tin mới và ghi title vào tệp tin đó
with open(log_file_path, 'w', encoding='utf-8') as file:
file.write(title + '\n')
else:
# Nếu tệp tin log đã tồn tại, mở tệp tin và chèn title vào cuối tệp tin
with open(log_file_path, 'a', encoding='utf-8') as file:
file.write(title + '\n')
except Exception as e:
print(f"Error logging song title: {e}")

async def remove_first_line_from_log():
log_file_path = "C:\\Bot Music 2\\song_log.txt"
try:
with open(log_file_path, "r", encoding="utf-8") as f:
lines = f.readlines()
# Xóa dòng đầu tiên trong list lines
lines = lines[1:]
with open(log_file_path, "w", encoding="utf-8") as f:
for line in lines:
f.write(line)
except Exception as e:
print(f"Error removing first line from log: {e}")

async def clear_log_file():
log_file_path = "C:\\Bot Music 2\\song_log.txt"
try:
with open(log_file_path, "w", encoding="utf-8") as f:
f.truncate(0)
except Exception as e:
print(f"Error clearing log file: {e}")

async def play_next_song(guild_id, queues, voice_client, skip=False):
queue = queues.get(guild_id, [])
if queue:
player = queue.pop(0)
voice_client.play(player, after=lambda e: asyncio.run_coroutine_threadsafe(play_next_song(guild_id, queues, voice_client, skip=False), voice_client.loop))
if skip:
return
else:
await remove_first_line_from_log()  # Xóa dòng đầu tiên trong file log
elif skip:
await remove_first_line_from_log()  # Xóa dòng đầu tiên trong file log
await voice_client.disconnect()
del voice_client[guild_id]  # Xóa voice_client sau khi dừng
else:
await clear_log_file()  # Xóa dòng đầu tiên trong file log
await voice_client.disconnect()
del voice_client[guild_id]  # Xóa voice_client sau khi dừng
Я пробовал задавать вопросы ChatGPT, Gemini или Bing, и они всегда приводили меня к череде ошибок, которые невозможно устранить. Эта ошибка возникает только тогда, когда песня естественным образом завершает воспроизведение из-за ее продолжительности. Если песня воспроизводится и я использую команду !skip, следующая песня в очереди будет воспроизводиться и работать нормально. Я заметил, что если песня заканчивается естественным образом, очередь песен также немедленно очищается. Надеюсь, кто-нибудь сможет мне с этим помочь

Подробнее здесь: https://stackoverflow.com/questions/782 ... bots-queue

Вернуться в «Python»