added ff/rewind & make album art load just bytes instead of writing to a file
This commit is contained in:
1 parent
c1c640f837
commit
7ad56fa4be
3 files changed
+56
-18
No files matched your search
+10
@@ -386,6 +386,16 @@ class SubpyConn:
|
|||||||
with open(path if path else 'cover.png', 'wb') as file:
|
with open(path if path else 'cover.png', 'wb') as file:
|
||||||
file.write(r.content)
|
file.write(r.content)
|
||||||
|
|
||||||
|
def getCoverArtRaw(self, cover_art_id: str) -> bytes:
|
||||||
|
url = self.base_url + '/rest/getCoverArt?'
|
||||||
|
|
||||||
|
payload = self._getBasePayload()
|
||||||
|
payload['id'] = cover_art_id
|
||||||
|
|
||||||
|
r = requests.get(url + self._encodePayload(payload))
|
||||||
|
|
||||||
|
return r.content
|
||||||
|
|
||||||
def getSong(self, song_id: str) -> Song:
|
def getSong(self, song_id: str) -> Song:
|
||||||
url = self.base_url + '/rest/getSong?'
|
url = self.base_url + '/rest/getSong?'
|
||||||
|
|
||||||
|
|||||||
+34
-7
@@ -25,6 +25,7 @@ from textual.widgets.option_list import Option
|
|||||||
from textual.timer import Timer
|
from textual.timer import Timer
|
||||||
|
|
||||||
from rich_pixels import Pixels
|
from rich_pixels import Pixels
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
u = 'pseudo'
|
u = 'pseudo'
|
||||||
p = 'telegram9dock-MICHEL'
|
p = 'telegram9dock-MICHEL'
|
||||||
@@ -286,17 +287,18 @@ class Favourites(Screen):
|
|||||||
if song.id == self.selected_song_id:
|
if song.id == self.selected_song_id:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
# TODO : Maybe should just take bytes instead of saving it as a file
|
|
||||||
class CoverArtPixels(Container):
|
class CoverArtPixels(Container):
|
||||||
|
|
||||||
def __init__(self, cover_art_id: str):
|
cover_art_id: str | None = None
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
|
def set_cover_art(self, cover_art_id: str) -> None:
|
||||||
self.cover_art_id = cover_art_id
|
self.cover_art_id = cover_art_id
|
||||||
conn.getCoverArt(cover_art_id, path=f'art/{cover_art_id}.png')
|
|
||||||
|
|
||||||
def render(self) -> RenderResult:
|
def render(self) -> RenderResult:
|
||||||
|
|
||||||
|
if not self.cover_art_id:
|
||||||
|
return ""
|
||||||
|
|
||||||
# Make the size square
|
# Make the size square
|
||||||
width, height = self.size
|
width, height = self.size
|
||||||
|
|
||||||
@@ -305,7 +307,8 @@ class CoverArtPixels(Container):
|
|||||||
elif height > width:
|
elif height > width:
|
||||||
height = width
|
height = width
|
||||||
|
|
||||||
return Pixels().from_image_path(f'art/{self.cover_art_id}.png', resize=(width, height))
|
image = Image.open(io.BytesIO(conn.getCoverArtRaw(self.cover_art_id)))
|
||||||
|
return Pixels().from_image(image, resize=(width, height))
|
||||||
|
|
||||||
class MainView(Screen):
|
class MainView(Screen):
|
||||||
CSS_PATH = 'main.tcss'
|
CSS_PATH = 'main.tcss'
|
||||||
@@ -317,6 +320,7 @@ class MainView(Screen):
|
|||||||
yield Label("Playing")
|
yield Label("Playing")
|
||||||
yield DataTable(id="currently_playing")
|
yield DataTable(id="currently_playing")
|
||||||
yield ProgressBar()
|
yield ProgressBar()
|
||||||
|
yield CoverArtPixels()
|
||||||
with Vertical(classes="column"):
|
with Vertical(classes="column"):
|
||||||
yield Label("Queue")
|
yield Label("Queue")
|
||||||
yield DataTable(id="queue")
|
yield DataTable(id="queue")
|
||||||
@@ -333,7 +337,7 @@ class MainView(Screen):
|
|||||||
currentlyPlaying.add_columns("", "")
|
currentlyPlaying.add_columns("", "")
|
||||||
|
|
||||||
@on(events.ScreenResume)
|
@on(events.ScreenResume)
|
||||||
async def screen_resumed(self, event: events.ScreenResume) -> None:
|
def screen_resumed(self, event: events.ScreenResume) -> None:
|
||||||
app.sub_title = "Overview"
|
app.sub_title = "Overview"
|
||||||
|
|
||||||
# Update Queue Table
|
# Update Queue Table
|
||||||
@@ -359,7 +363,7 @@ class MainView(Screen):
|
|||||||
currentlyPlaying.add_row("Track Number", song.trackNumber)
|
currentlyPlaying.add_row("Track Number", song.trackNumber)
|
||||||
currentlyPlaying.add_row("Bit Rate", song.bitRate)
|
currentlyPlaying.add_row("Bit Rate", song.bitRate)
|
||||||
|
|
||||||
await self.query_one('#info').mount(CoverArtPixels(app.currently_playing.id))
|
self.query_one(CoverArtPixels).set_cover_art(app.currently_playing.id)
|
||||||
|
|
||||||
def _clear_table(self, table_id: str) -> None:
|
def _clear_table(self, table_id: str) -> None:
|
||||||
table: DataTable = self.query_one(table_id)
|
table: DataTable = self.query_one(table_id)
|
||||||
@@ -374,7 +378,9 @@ class MainView(Screen):
|
|||||||
|
|
||||||
class TextualSubpyPlayer(App):
|
class TextualSubpyPlayer(App):
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
|
("r", "rewind()", "⏪"),
|
||||||
("space", "play_pause_song()", "⏯️"),
|
("space", "play_pause_song()", "⏯️"),
|
||||||
|
("s", "skip()", "⏭️"),
|
||||||
("f1", "switch_mode('main')", "Overview"),
|
("f1", "switch_mode('main')", "Overview"),
|
||||||
("f2", "switch_mode('artists')", "Artists"),
|
("f2", "switch_mode('artists')", "Artists"),
|
||||||
("f3", "switch_mode('albums')", "Albums"),
|
("f3", "switch_mode('albums')", "Albums"),
|
||||||
@@ -393,6 +399,7 @@ class TextualSubpyPlayer(App):
|
|||||||
currently_playing: SubSonic.Song | None = None
|
currently_playing: SubSonic.Song | None = None
|
||||||
song_queue: list[SubSonic.Song] = []
|
song_queue: list[SubSonic.Song] = []
|
||||||
user_queue: list[SubSonic.Song] = []
|
user_queue: list[SubSonic.Song] = []
|
||||||
|
play_history: list[SubSonic.Song] = []
|
||||||
is_paused: bool = False
|
is_paused: bool = False
|
||||||
place: int = 0
|
place: int = 0
|
||||||
|
|
||||||
@@ -430,6 +437,7 @@ class TextualSubpyPlayer(App):
|
|||||||
|
|
||||||
def check_done_playing(self) -> None:
|
def check_done_playing(self) -> None:
|
||||||
if not pygame.mixer.music.get_busy() and not self.is_paused:
|
if not pygame.mixer.music.get_busy() and not self.is_paused:
|
||||||
|
self.play_history.append(self.currently_playing)
|
||||||
queue = self.user_queue
|
queue = self.user_queue
|
||||||
queue.extend(self.song_queue)
|
queue.extend(self.song_queue)
|
||||||
|
|
||||||
@@ -439,6 +447,25 @@ class TextualSubpyPlayer(App):
|
|||||||
|
|
||||||
self.check_playing_timer.stop()
|
self.check_playing_timer.stop()
|
||||||
|
|
||||||
|
def action_skip(self) -> None:
|
||||||
|
|
||||||
|
if self.check_playing_timer:
|
||||||
|
self.check_playing_timer.stop()
|
||||||
|
|
||||||
|
if self.currently_playing:
|
||||||
|
self.play_history.append(self.currently_playing)
|
||||||
|
|
||||||
|
queue = self.user_queue
|
||||||
|
queue.extend(self.song_queue)
|
||||||
|
|
||||||
|
self.play_song(queue.pop(0))
|
||||||
|
|
||||||
|
def action_rewind(self) -> None:
|
||||||
|
if self.check_playing_timer:
|
||||||
|
self.check_playing_timer.stop()
|
||||||
|
|
||||||
|
self.play_song(self.play_history.pop())
|
||||||
|
|
||||||
# def update_progress(self) -> None:
|
# def update_progress(self) -> None:
|
||||||
# self.query_one(ProgressBar).advance(1)
|
# self.query_one(ProgressBar).advance(1)
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -1,11 +1,12 @@
|
|||||||
[2025-01-24 17:00:13,155] DEBUG in selector_events: Using selector: EpollSelector
|
[2025-01-24 21:34:24,903] DEBUG in selector_events: Using selector: EpollSelector
|
||||||
[2025-01-24 17:00:15,224] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
[2025-01-24 21:34:26,609] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
||||||
[2025-01-24 17:00:15,621] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/getStarred?u=pseudo&t=df47a647004f9967d54a717354d758bd&s=OEYQY6IP&v=1.16.1&c=testing&f=json HTTP/1.1" 200 None
|
[2025-01-24 21:34:26,646] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/getPlaylists?u=pseudo&t=117b12afec7228071d8e5423a81373a8&s=K6WPAIKV&v=1.16.1&c=testing&f=json HTTP/1.1" 200 705
|
||||||
[2025-01-24 17:00:18,614] DEBUG in screens-test: Playing song rap music by Lil Darkie.
|
[2025-01-24 21:34:28,309] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
||||||
[2025-01-24 17:00:18,615] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
[2025-01-24 21:34:28,345] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/getPlaylist?u=pseudo&t=93ebc246f6838084d07ac50c4bf787be&s=Z3D6WNNK&v=1.16.1&c=testing&f=json&id=9d76a86b-901f-4727-a2ec-01210157ff01 HTTP/1.1" 200 None
|
||||||
[2025-01-24 17:00:18,843] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/stream?u=pseudo&t=17ea6e0ce1111a102699f10662381805&s=UUJ177KV&v=1.16.1&c=testing&id=62196e9d0d531adff738bf47349cbfc6 HTTP/1.1" 200 8464191
|
[2025-01-24 21:34:30,632] DEBUG in screens-test: Playing song Midian by Yakui the Maid.
|
||||||
[2025-01-24 17:00:20,392] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
[2025-01-24 21:34:30,633] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
||||||
[2025-01-24 17:00:20,628] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/getCoverArt?u=pseudo&t=36a4b74c419b83821131781619811886&s=I4SC818D&v=1.16.1&c=testing&id=62196e9d0d531adff738bf47349cbfc6 HTTP/1.1" 200 None
|
[2025-01-24 21:34:30,662] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/stream?u=pseudo&t=d515d35181a76782a65a285398a605ea&s=WT0U93U8&v=1.16.1&c=testing&id=a57e00930bb5a1b50dcaf7c573f4ba66 HTTP/1.1" 200 20522391
|
||||||
[2025-01-24 17:03:36,276] DEBUG in screens-test: Playing song Pegasus Pro Ultra Fusion by Dan Terminus.
|
[2025-01-24 21:34:31,867] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
||||||
[2025-01-24 17:03:36,278] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
[2025-01-24 21:34:31,899] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/getCoverArt?u=pseudo&t=74f61a986314858ae80b67755cbb79cf&s=28V8171Q&v=1.16.1&c=testing&id=a57e00930bb5a1b50dcaf7c573f4ba66 HTTP/1.1" 200 None
|
||||||
[2025-01-24 17:03:36,763] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/stream?u=pseudo&t=3b4bd01e32919d4f7868d0f89e702b93&s=94XX1BQN&v=1.16.1&c=testing&id=49f56133cf2f7bc6462be7620113ee79 HTTP/1.1" 200 None
|
[2025-01-24 21:34:37,182] DEBUG in connectionpool: Starting new HTTPS connection (1): music.0x01fe.net:443
|
||||||
|
[2025-01-24 21:34:37,216] DEBUG in connectionpool: https://music.0x01fe.net:443 "GET /rest/getCoverArt?u=pseudo&t=d113293159ba7ab8bddc4749fe099c7c&s=8EL8LGE3&v=1.16.1&c=testing&id=a57e00930bb5a1b50dcaf7c573f4ba66 HTTP/1.1" 200 None
|
||||||
Reference in new issue
Block a user