fixed album art + updated now playing info
This commit is contained in:
1 parent
a07ee3bd52
commit
672f4f9142
3 files changed
+64
-20
No files matched your search
@@ -73,6 +73,7 @@ class Song:
|
|||||||
channelCount: int
|
channelCount: int
|
||||||
samplingRate: int
|
samplingRate: int
|
||||||
playCount: int | None
|
playCount: int | None
|
||||||
|
coverArtId: str | None
|
||||||
|
|
||||||
def __init__(self, info: dict | None = {}):
|
def __init__(self, info: dict | None = {}):
|
||||||
self.id = info['id'] if 'id' in info else ""
|
self.id = info['id'] if 'id' in info else ""
|
||||||
@@ -92,6 +93,7 @@ class Song:
|
|||||||
self.channelCount = int(info['channelCount']) if 'channelCount' in info else ""
|
self.channelCount = int(info['channelCount']) if 'channelCount' in info else ""
|
||||||
self.samplingRate = int(info['samplingRate']) if 'samplingRate' in info else ""
|
self.samplingRate = int(info['samplingRate']) if 'samplingRate' in info else ""
|
||||||
self.playCount = int(info['playCount']) if 'playCount' in info else ""
|
self.playCount = int(info['playCount']) if 'playCount' in info else ""
|
||||||
|
self.coverArtId = info['coverArt'] if 'coverArt' in info else None
|
||||||
|
|
||||||
class Artist:
|
class Artist:
|
||||||
id: str
|
id: str
|
||||||
|
|||||||
+53
-20
@@ -344,26 +344,50 @@ class QueueTable(Widget):
|
|||||||
return table
|
return table
|
||||||
|
|
||||||
# Fine to be a static renderable because it's not big enough to need a scroll
|
# Fine to be a static renderable because it's not big enough to need a scroll
|
||||||
class PlayingInfo(Widget):
|
class NowPlayingInfo(Container):
|
||||||
|
song = reactive[SubSonic.Song | None](None, layout=True)
|
||||||
|
|
||||||
|
# Place is from pygame.mixer.music.get_pos and is in ms
|
||||||
|
place: reactive[int] = reactive(0)
|
||||||
|
|
||||||
def render(self) -> RenderResult:
|
def render(self) -> RenderResult:
|
||||||
table = Table()
|
if self.song:
|
||||||
|
if self.song.title and self.song.artist:
|
||||||
|
|
||||||
table.add_column("")
|
# Convert seconds to MM:SS
|
||||||
table.add_column("", min_width=10)
|
duration_min, duration_sec = divmod(self.song.duration, 60)
|
||||||
table.show_header = False
|
duration_formatted = f"{duration_min:02d}:{duration_sec:02d}"
|
||||||
|
|
||||||
if app.currently_playing:
|
place_in_seconds = self.place // 1000
|
||||||
song = app.currently_playing
|
place_min, place_sec = divmod(place_in_seconds, 60)
|
||||||
table.add_row("Title", song.title)
|
place_formatted = f"{place_min:02d}:{place_sec:02d}"
|
||||||
table.add_row("Artist", song.artist)
|
|
||||||
table.add_row("Album", song.album)
|
|
||||||
table.add_row("Plays", str(song.playCount) if song.playCount else "0")
|
|
||||||
table.add_row("Duration", str(song.duration))
|
|
||||||
table.add_row("Track Number", str(song.trackNumber))
|
|
||||||
table.add_row("Bit Rate", str(song.bitRate))
|
|
||||||
|
|
||||||
return table
|
s = f"Song: {self.song.title}\nAlbum: {self.song.album}\nArtist: {self.song.artist}\nProgress: {place_formatted} / {duration_formatted}\n"
|
||||||
|
|
||||||
|
return s
|
||||||
|
return "Nothing Playing"
|
||||||
|
|
||||||
|
class NowPlaying(Widget):
|
||||||
|
def compose(self) -> ComposeResult:
|
||||||
|
yield NowPlayingInfo(id="textinfo")
|
||||||
|
yield CoverArtPixels(id="coverart")
|
||||||
|
|
||||||
|
def update_song(self, song: SubSonic.Song) -> None:
|
||||||
|
info = self.query_one(NowPlayingInfo)
|
||||||
|
info.song = song
|
||||||
|
|
||||||
|
if song.albumId:
|
||||||
|
cover_art = self.query_one(CoverArtPixels)
|
||||||
|
|
||||||
|
album = conn.getAlbumSongs(song.albumId)
|
||||||
|
if album:
|
||||||
|
cover_id: str | None = album[0].coverArtId
|
||||||
|
if cover_id:
|
||||||
|
cover_art.get_cover_art(cover_id)
|
||||||
|
|
||||||
|
def set_place(self, place: int) -> None:
|
||||||
|
info = self.query_one(NowPlayingInfo)
|
||||||
|
info.place = place
|
||||||
|
|
||||||
# https://textual.textualize.io/widgets/data_table/#labeled-rows
|
# https://textual.textualize.io/widgets/data_table/#labeled-rows
|
||||||
# Add this ^ to queue sometime plz
|
# Add this ^ to queue sometime plz
|
||||||
@@ -374,10 +398,8 @@ class MainView(Screen):
|
|||||||
yield Header(icon="")
|
yield Header(icon="")
|
||||||
with Horizontal():
|
with Horizontal():
|
||||||
with Vertical(classes="info", id='info'):
|
with Vertical(classes="info", id='info'):
|
||||||
yield Label("Playing")
|
yield NowPlaying(id="now-playing")
|
||||||
yield PlayingInfo()
|
|
||||||
yield ProgressBar()
|
yield ProgressBar()
|
||||||
yield CoverArtPixels(id="coverart")
|
|
||||||
with Vertical(classes="column"):
|
with Vertical(classes="column"):
|
||||||
yield Label("Queue")
|
yield Label("Queue")
|
||||||
yield DataTable(id="queue", cursor_type='row')
|
yield DataTable(id="queue", cursor_type='row')
|
||||||
@@ -392,6 +414,7 @@ class MainView(Screen):
|
|||||||
def screen_resumed(self, event: events.ScreenResume) -> None:
|
def screen_resumed(self, event: events.ScreenResume) -> None:
|
||||||
app.sub_title = "Overview"
|
app.sub_title = "Overview"
|
||||||
self.update_queue()
|
self.update_queue()
|
||||||
|
app.update_now_playing()
|
||||||
|
|
||||||
def update_queue(self) -> None:
|
def update_queue(self) -> None:
|
||||||
table = self.query_one(DataTable)
|
table = self.query_one(DataTable)
|
||||||
@@ -457,8 +480,10 @@ class TextualSubpyPlayer(App):
|
|||||||
pygame.mixer.music.play()
|
pygame.mixer.music.play()
|
||||||
|
|
||||||
self.check_playing_timer = self.set_interval(1 / 5, self.check_done_playing, pause=False)
|
self.check_playing_timer = self.set_interval(1 / 5, self.check_done_playing, pause=False)
|
||||||
|
self.progess_timer = self.set_interval(0.3, self.update_progress, pause=False)
|
||||||
|
|
||||||
self.update_queue_table()
|
self.update_queue_table()
|
||||||
|
self.update_now_playing()
|
||||||
|
|
||||||
# playingLabel: Label = self.query_one(Label)
|
# playingLabel: Label = self.query_one(Label)
|
||||||
# playingLabel.
|
# playingLabel.
|
||||||
@@ -497,8 +522,10 @@ class TextualSubpyPlayer(App):
|
|||||||
|
|
||||||
self.play_song(self.play_history.pop())
|
self.play_song(self.play_history.pop())
|
||||||
|
|
||||||
# def update_progress(self) -> None:
|
def update_progress(self) -> None:
|
||||||
# self.query_one(ProgressBar).advance(1)
|
if isinstance(self.screen, MainView) and self.currently_playing:
|
||||||
|
now_playing = self.screen.query_one(NowPlaying)
|
||||||
|
now_playing.set_place(pygame.mixer.music.get_pos())
|
||||||
|
|
||||||
def queue_song(self, song: SubSonic.Song) -> None:
|
def queue_song(self, song: SubSonic.Song) -> None:
|
||||||
logging.debug(f'Queue\'d song "{song.title}" by {song.artist}.')
|
logging.debug(f'Queue\'d song "{song.title}" by {song.artist}.')
|
||||||
@@ -522,6 +549,12 @@ class TextualSubpyPlayer(App):
|
|||||||
pygame.mixer.music.unpause()
|
pygame.mixer.music.unpause()
|
||||||
self.is_paused = False
|
self.is_paused = False
|
||||||
|
|
||||||
|
def update_now_playing(self) -> None:
|
||||||
|
if isinstance(self.screen, MainView) and self.currently_playing:
|
||||||
|
logging.debug("Updating now playing widget")
|
||||||
|
now_playing = self.screen.query_one(NowPlaying)
|
||||||
|
now_playing.update_song(self.currently_playing)
|
||||||
|
|
||||||
def update_queue_table(self) -> None:
|
def update_queue_table(self) -> None:
|
||||||
if isinstance(self.screen, MainView):
|
if isinstance(self.screen, MainView):
|
||||||
logging.debug("Updating queue through app")
|
logging.debug("Updating queue through app")
|
||||||
|
|||||||
@@ -2,3 +2,12 @@
|
|||||||
width: 30%;
|
width: 30%;
|
||||||
padding-right: 2;
|
padding-right: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#textinfo {
|
||||||
|
height: 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#coverart {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user