now playing feature added
This commit is contained in:
1 parent
aaad0b6ed6
commit
7367eb2cc4
4 files changed
+58
-3
No files matched your search
@@ -34,6 +34,7 @@ class Music(PlayerCommands, QueueCommands, MusicEvents, RadioCommands, RadioEven
|
|||||||
self._states: dict[int, GuildState] = {}
|
self._states: dict[int, GuildState] = {}
|
||||||
self._voice_channels: dict[int, int] = {} # guild_id → voice channel id (for status cleanup)
|
self._voice_channels: dict[int, int] = {} # guild_id → voice channel id (for status cleanup)
|
||||||
self._radio_channels: dict[int, int] = {} # guild_id → text channel id (for drop notifications)
|
self._radio_channels: dict[int, int] = {} # guild_id → text channel id (for drop notifications)
|
||||||
|
self._music_channels: dict[int, int] = {} # guild_id → text channel id (for now-playing announcements)
|
||||||
self._locks: dict[int, asyncio.Lock] = {}
|
self._locks: dict[int, asyncio.Lock] = {}
|
||||||
|
|
||||||
# Load radio stations
|
# Load radio stations
|
||||||
|
|||||||
@@ -55,10 +55,12 @@ class PlayerCommands:
|
|||||||
|
|
||||||
if not vc.playing and not vc.paused and st.queue:
|
if not vc.playing and not vc.paused and st.queue:
|
||||||
st.current = st.queue.popleft()
|
st.current = st.queue.popleft()
|
||||||
|
st.suppress_np = True
|
||||||
await vc.play(st.current)
|
await vc.play(st.current)
|
||||||
await self._set_channel_status(vc, st.current)
|
await self._set_channel_status(vc, st.current)
|
||||||
|
|
||||||
st.mode = MODE_MUSIC
|
st.mode = MODE_MUSIC
|
||||||
|
self._music_channels[ctx.guild.id] = ctx.channel.id
|
||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="📋 Playlist Queued",
|
title="📋 Playlist Queued",
|
||||||
@@ -74,6 +76,8 @@ class PlayerCommands:
|
|||||||
track = results[0]
|
track = results[0]
|
||||||
track.extras = {"requester_id": ctx.author.id}
|
track.extras = {"requester_id": ctx.author.id}
|
||||||
|
|
||||||
|
self._music_channels[ctx.guild.id] = ctx.channel.id
|
||||||
|
|
||||||
if vc.playing or vc.paused:
|
if vc.playing or vc.paused:
|
||||||
st.queue.append(track)
|
st.queue.append(track)
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -89,6 +93,7 @@ class PlayerCommands:
|
|||||||
return await ctx.reply(embed=embed)
|
return await ctx.reply(embed=embed)
|
||||||
|
|
||||||
st.current = track
|
st.current = track
|
||||||
|
st.suppress_np = True
|
||||||
await vc.play(track)
|
await vc.play(track)
|
||||||
await self._set_channel_status(vc, track)
|
await self._set_channel_status(vc, track)
|
||||||
st.mode = MODE_MUSIC
|
st.mode = MODE_MUSIC
|
||||||
@@ -159,6 +164,7 @@ class PlayerCommands:
|
|||||||
|
|
||||||
self._voice_channels.pop(ctx.guild.id, None)
|
self._voice_channels.pop(ctx.guild.id, None)
|
||||||
self._radio_channels.pop(ctx.guild.id, None)
|
self._radio_channels.pop(ctx.guild.id, None)
|
||||||
|
self._music_channels.pop(ctx.guild.id, None)
|
||||||
self._locks.pop(ctx.guild.id, None)
|
self._locks.pop(ctx.guild.id, None)
|
||||||
|
|
||||||
msg = "⏹️ Stopped radio and disconnected." if current_mode == MODE_RADIO else "⏹️ Stopped and disconnected."
|
msg = "⏹️ Stopped radio and disconnected." if current_mode == MODE_RADIO else "⏹️ Stopped and disconnected."
|
||||||
|
|||||||
+50
-3
@@ -2,7 +2,8 @@ import wavelink
|
|||||||
import discord
|
import discord
|
||||||
import logging
|
import logging
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from ..shared.constants import LOOP_TRACK, LOOP_QUEUE, MODE_RADIO
|
from ..shared.constants import LOOP_TRACK, LOOP_QUEUE, MODE_RADIO, MODE_MUSIC, C_MAIN
|
||||||
|
from ..shared.utils import fmt_duration
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ class MusicEvents:
|
|||||||
st.queue.clear()
|
st.queue.clear()
|
||||||
self._locks.pop(guild_id, None)
|
self._locks.pop(guild_id, None)
|
||||||
self._radio_channels.pop(guild_id, None)
|
self._radio_channels.pop(guild_id, None)
|
||||||
|
self._music_channels.pop(guild_id, None)
|
||||||
await self._clear_channel_status(guild_id)
|
await self._clear_channel_status(guild_id)
|
||||||
|
|
||||||
# ── track end → advance queue ─────────────────────────────────────────────
|
# ── track end → advance queue ─────────────────────────────────────────────
|
||||||
@@ -118,7 +120,7 @@ class MusicEvents:
|
|||||||
st.mode = None
|
st.mode = None
|
||||||
await self._set_channel_status(player)
|
await self._set_channel_status(player)
|
||||||
|
|
||||||
# ── track start → update voice status ─────────────────────────────────────
|
# ── track start → update voice status & announce ─────────────────────────
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_wavelink_track_start(self, payload: wavelink.TrackStartEventPayload):
|
async def on_wavelink_track_start(self, payload: wavelink.TrackStartEventPayload):
|
||||||
player: wavelink.Player = payload.player
|
player: wavelink.Player = payload.player
|
||||||
@@ -126,6 +128,51 @@ class MusicEvents:
|
|||||||
return
|
return
|
||||||
st = self.state(player.guild.id)
|
st = self.state(player.guild.id)
|
||||||
st.current = payload.track
|
st.current = payload.track
|
||||||
# Radio sets its own title; only update status for music mode
|
|
||||||
if st.mode != MODE_RADIO:
|
if st.mode != MODE_RADIO:
|
||||||
await self._set_channel_status(player, st.current)
|
await self._set_channel_status(player, st.current)
|
||||||
|
|
||||||
|
# Send polished now-playing announcement to the music text channel
|
||||||
|
if not st.suppress_np:
|
||||||
|
await self._send_now_playing(player.guild.id, st.current)
|
||||||
|
st.suppress_np = False
|
||||||
|
|
||||||
|
# ── now-playing announcement helper ───────────────────────────────────────
|
||||||
|
async def _send_now_playing(self, guild_id: int, track: wavelink.Playable):
|
||||||
|
"""Send a compact, polished 'Now Playing' embed to the music channel."""
|
||||||
|
channel_id = self._music_channels.get(guild_id)
|
||||||
|
if channel_id is None:
|
||||||
|
return
|
||||||
|
guild = self.bot.get_guild(guild_id)
|
||||||
|
if guild is None:
|
||||||
|
return
|
||||||
|
channel = guild.get_channel_or_thread(channel_id)
|
||||||
|
if channel is None:
|
||||||
|
self._music_channels.pop(guild_id, None)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Build a clean now-playing embed
|
||||||
|
embed = discord.Embed(color=C_MAIN)
|
||||||
|
desc_parts = [f"## 🎵 {track.title}"]
|
||||||
|
if track.author:
|
||||||
|
desc_parts.append(f"-# {track.author}")
|
||||||
|
embed.description = "\n".join(desc_parts)
|
||||||
|
|
||||||
|
meta: list[str] = []
|
||||||
|
if track.length:
|
||||||
|
meta.append(f"`{fmt_duration(track.length)}`")
|
||||||
|
if track.extras and isinstance(track.extras, dict):
|
||||||
|
requester_id = track.extras.get("requester_id")
|
||||||
|
if requester_id:
|
||||||
|
meta.append(f"Requested by <@{requester_id}>")
|
||||||
|
if meta:
|
||||||
|
embed.add_field(name="\u200b", value=" · ".join(meta), inline=False)
|
||||||
|
|
||||||
|
if track.artwork:
|
||||||
|
embed.set_thumbnail(url=track.artwork)
|
||||||
|
embed.set_footer(text="yuuka music")
|
||||||
|
|
||||||
|
try:
|
||||||
|
await channel.send(embed=embed)
|
||||||
|
except Exception:
|
||||||
|
log.warning(f"Failed to send now-playing message in guild {guild_id}", exc_info=True)
|
||||||
@@ -11,6 +11,7 @@ class GuildState:
|
|||||||
self.autoplay: bool = False
|
self.autoplay: bool = False
|
||||||
self.current: wavelink.Playable | None = None
|
self.current: wavelink.Playable | None = None
|
||||||
self.mode: str | None = None
|
self.mode: str | None = None
|
||||||
|
self.suppress_np: bool = False # skip auto now-playing embed (set by !play)
|
||||||
|
|
||||||
def push_history(self, track: wavelink.Playable):
|
def push_history(self, track: wavelink.Playable):
|
||||||
self.history.insert(0, track)
|
self.history.insert(0, track)
|
||||||
|
|||||||
Reference in new issue
Block a user