Compare commits
No commits in common. "2204c24e29fe2bd1668a632af77eb31fae2e738b" and "63a2db82785a0b92d4c4de1c0838ee126b4c2a0f" have entirely different histories.
2204c24e29
...
63a2db8278
@ -153,8 +153,11 @@ async def queue_or_play(message, edited=False):
|
|||||||
else:
|
else:
|
||||||
players[message.guild.id].queue_add(queued)
|
players[message.guild.id].queue_add(queued)
|
||||||
|
|
||||||
if not message.guild.voice_client.source:
|
if (
|
||||||
play_next(message, first=True)
|
not message.guild.voice_client.is_playing()
|
||||||
|
and not message.guild.voice_client.is_paused()
|
||||||
|
):
|
||||||
|
play_next(message)
|
||||||
elif args.now:
|
elif args.now:
|
||||||
message.guild.voice_client.stop()
|
message.guild.voice_client.stop()
|
||||||
else:
|
else:
|
||||||
@ -216,29 +219,10 @@ async def playing(message):
|
|||||||
if not command_allowed(message):
|
if not command_allowed(message):
|
||||||
return
|
return
|
||||||
|
|
||||||
if source := message.guild.voice_client.source:
|
if message.guild.voice_client.source:
|
||||||
bar_length = 35
|
|
||||||
progress = source.original.progress / source.duration
|
|
||||||
|
|
||||||
embed = disnake.Embed(
|
|
||||||
color=constants.EMBED_COLOR,
|
|
||||||
title=source.title,
|
|
||||||
description=f"{'⏸️ ' if message.guild.voice_client.is_paused() else ''}"
|
|
||||||
f"`[{'#'*int(progress * bar_length)}{'-'*int((1 - progress) * bar_length)}]`"
|
|
||||||
f"{youtubedl.format_duration(int(source.original.progress))} / {youtubedl.format_duration(source.duration)}",
|
|
||||||
url=source.original_url,
|
|
||||||
)
|
|
||||||
embed.add_field(name="Volume", value=f"{int(source.volume*100)}%")
|
|
||||||
embed.add_field(name="Views", value=f"{source.view_count:,}")
|
|
||||||
embed.add_field(
|
|
||||||
name="Queuer",
|
|
||||||
value=players[message.guild.id].current.trigger_message.author.mention,
|
|
||||||
)
|
|
||||||
embed.set_image(source.thumbnail_url)
|
|
||||||
|
|
||||||
await utils.reply(
|
await utils.reply(
|
||||||
message,
|
message,
|
||||||
embed=embed,
|
f"{'(paused) ' if message.guild.voice_client.is_paused() else ''} {players[message.guild.id].current.format(show_queuer=True)}",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await utils.reply(
|
await utils.reply(
|
||||||
@ -260,7 +244,10 @@ async def skip(message):
|
|||||||
else:
|
else:
|
||||||
message.guild.voice_client.stop()
|
message.guild.voice_client.stop()
|
||||||
await utils.add_check_reaction(message)
|
await utils.add_check_reaction(message)
|
||||||
if not message.guild.voice_client.source:
|
if (
|
||||||
|
not message.guild.voice_client.is_playing()
|
||||||
|
and not message.guild.voice_client.is_paused()
|
||||||
|
):
|
||||||
play_next(message)
|
play_next(message)
|
||||||
|
|
||||||
|
|
||||||
@ -360,7 +347,7 @@ def play_after_callback(e, message, once):
|
|||||||
play_next(message)
|
play_next(message)
|
||||||
|
|
||||||
|
|
||||||
def play_next(message, once=False, first=False):
|
def play_next(message, once=False):
|
||||||
message.guild.voice_client.stop()
|
message.guild.voice_client.stop()
|
||||||
if players[message.guild.id].queue:
|
if players[message.guild.id].queue:
|
||||||
queued = players[message.guild.id].queue_pop()
|
queued = players[message.guild.id].queue_pop()
|
||||||
@ -374,7 +361,7 @@ def play_next(message, once=False, first=False):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
client.loop.create_task(
|
client.loop.create_task(
|
||||||
utils.channel_send(message, queued.format(show_queuer=not first))
|
utils.channel_send(message, f"**0.** {queued.format(show_queuer=True)}")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
4
tasks.py
4
tasks.py
@ -11,9 +11,9 @@ async def cleanup():
|
|||||||
await asyncio.sleep(3600)
|
await asyncio.sleep(3600)
|
||||||
|
|
||||||
targets = []
|
targets = []
|
||||||
for guild_id, player in players.items():
|
for id, player in players:
|
||||||
if len(player.queue) == 0:
|
if len(player.queue) == 0:
|
||||||
targets.append(guild_id)
|
targets.append(id)
|
||||||
for target in targets:
|
for target in targets:
|
||||||
del players[target]
|
del players[target]
|
||||||
|
|
||||||
|
48
youtubedl.py
48
youtubedl.py
@ -11,33 +11,14 @@ import constants
|
|||||||
ytdl = yt_dlp.YoutubeDL(constants.YTDL_OPTIONS)
|
ytdl = yt_dlp.YoutubeDL(constants.YTDL_OPTIONS)
|
||||||
|
|
||||||
|
|
||||||
class TrackedAudioSource(disnake.AudioSource):
|
|
||||||
def __init__(self, source):
|
|
||||||
self._source = source
|
|
||||||
self.count = 0
|
|
||||||
|
|
||||||
def read(self) -> bytes:
|
|
||||||
data = self._source.read()
|
|
||||||
if data:
|
|
||||||
self.count += 1
|
|
||||||
return data
|
|
||||||
|
|
||||||
@property
|
|
||||||
def progress(self) -> float:
|
|
||||||
return self.count * 0.02
|
|
||||||
|
|
||||||
|
|
||||||
class YTDLSource(disnake.PCMVolumeTransformer):
|
class YTDLSource(disnake.PCMVolumeTransformer):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, source: TrackedAudioSource, *, data: dict[str, Any], volume: float = 0.5
|
self, source: disnake.AudioSource, *, data: dict[str, Any], volume: float = 0.5
|
||||||
):
|
):
|
||||||
super().__init__(source, volume)
|
super().__init__(source, volume)
|
||||||
|
|
||||||
self.duration = data.get("duration")
|
|
||||||
self.original_url = data.get("original_url")
|
|
||||||
self.thumbnail_url = data.get("thumbnail")
|
|
||||||
self.title = data.get("title")
|
self.title = data.get("title")
|
||||||
self.view_count = data.get("view_count")
|
self.original_url = data.get("original_url")
|
||||||
|
self.duration = data.get("duration")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def from_url(
|
async def from_url(
|
||||||
@ -56,11 +37,9 @@ class YTDLSource(disnake.PCMVolumeTransformer):
|
|||||||
data = data["entries"][0]
|
data = data["entries"][0]
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
TrackedAudioSource(
|
|
||||||
disnake.FFmpegPCMAudio(
|
disnake.FFmpegPCMAudio(
|
||||||
data["url"] if stream else ytdl.prepare_filename(data),
|
data["url"] if stream else ytdl.prepare_filename(data),
|
||||||
before_options="-vn -reconnect 1",
|
before_options="-vn -reconnect 1",
|
||||||
)
|
|
||||||
),
|
),
|
||||||
data=data,
|
data=data,
|
||||||
)
|
)
|
||||||
@ -80,7 +59,7 @@ class QueuedSong:
|
|||||||
def format(self, show_queuer=False, hide_preview=False, multiline=False) -> str:
|
def format(self, show_queuer=False, hide_preview=False, multiline=False) -> str:
|
||||||
if multiline:
|
if multiline:
|
||||||
return (
|
return (
|
||||||
f"[`{self.player.title}`]({'<' if hide_preview else ''}{self.player.original_url}{'>' if hide_preview else ''})\n**duration:** {format_duration(self.player.duration) if self.player.duration else '[live]'}"
|
f"[`{self.player.title}`]({'<' if hide_preview else ''}{self.player.original_url}{'>' if hide_preview else ''})\n**duration:** {self.format_duration(self.player.duration) if self.player.duration else '[live]'}"
|
||||||
+ (
|
+ (
|
||||||
f", **queuer:** <@{self.trigger_message.author.id}>"
|
f", **queuer:** <@{self.trigger_message.author.id}>"
|
||||||
if show_queuer
|
if show_queuer
|
||||||
@ -89,10 +68,18 @@ class QueuedSong:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return (
|
return (
|
||||||
f"[`{self.player.title}`]({'<' if hide_preview else ''}{self.player.original_url}{'>' if hide_preview else ''}) **[{format_duration(self.player.duration) if self.player.duration else 'live'}]**"
|
f"[`{self.player.title}`]({'<' if hide_preview else ''}{self.player.original_url}{'>' if hide_preview else ''}) **[{self.format_duration(self.player.duration) if self.player.duration else 'live'}]**"
|
||||||
+ (f" (<@{self.trigger_message.author.id}>)" if show_queuer else "")
|
+ (f" (<@{self.trigger_message.author.id}>)" if show_queuer else "")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def format_duration(self, duration: int) -> str:
|
||||||
|
hours, duration = divmod(duration, 3600)
|
||||||
|
minutes, duration = divmod(duration, 60)
|
||||||
|
segments = [hours, minutes, duration]
|
||||||
|
if len(segments) == 3 and segments[0] == 0:
|
||||||
|
del segments[0]
|
||||||
|
return f"{':'.join(f'{s:0>2}' for s in segments)}"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
@ -117,15 +104,6 @@ class QueuedPlayer:
|
|||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
def format_duration(duration: int) -> str:
|
|
||||||
hours, duration = divmod(duration, 3600)
|
|
||||||
minutes, duration = divmod(duration, 60)
|
|
||||||
segments = [hours, minutes, duration]
|
|
||||||
if len(segments) == 3 and segments[0] == 0:
|
|
||||||
del segments[0]
|
|
||||||
return f"{':'.join(f'{s:0>2}' for s in segments)}"
|
|
||||||
|
|
||||||
|
|
||||||
def __reload_module__():
|
def __reload_module__():
|
||||||
global ytdl
|
global ytdl
|
||||||
ytdl = yt_dlp.YoutubeDL(constants.YTDL_OPTIONS)
|
ytdl = yt_dlp.YoutubeDL(constants.YTDL_OPTIONS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user