From b3468208418a67fa162d3a4eae6b86290ee17cb1 Mon Sep 17 00:00:00 2001 From: Rafael Moraes <50295204+glomatico@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:59:52 -0300 Subject: [PATCH] Support FLAC audio playback and file lookup --- votify/interface/audio.py | 13 ++++++++----- votify/interface/base.py | 11 ++++++++++- votify/interface/interface.py | 3 ++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/votify/interface/audio.py b/votify/interface/audio.py index 4d6af32..6141785 100644 --- a/votify/interface/audio.py +++ b/votify/interface/audio.py @@ -51,7 +51,7 @@ class SpotifyAudioInterface(SpotifyBaseInterface): audio_track=StreamInfo( stream_url=stream_url, widevine_pssh=pssh, - file_format="mp4", + file_format="flac" if audio_quality == AudioQuality.FLAC else "mp4", ), ) @@ -67,12 +67,15 @@ class SpotifyAudioInterface(SpotifyBaseInterface): playback_info: dict, format_id: str, ) -> str | None: + manifest_key = ( + "file_ids_mp4flac" + if self.audio_quality == AudioQuality.FLAC + else "file_ids_mp4" + ) file_id = next( ( file_info["file_id"] - for file_info in playback_info.get("manifest", {}).get( - "file_ids_mp4", [] - ) + for file_info in playback_info.get("manifest", {}).get(manifest_key, []) if file_info["format"] == format_id ), None, @@ -95,7 +98,7 @@ class SpotifyAudioInterface(SpotifyBaseInterface): file_id: str, ) -> str: seek_table_response = await self.api.get_seek_table(file_id) - pssh = seek_table_response["pssh"] + pssh = seek_table_response["pssh_widevine"] logger.debug(f"Received PSSH: {pssh}") diff --git a/votify/interface/base.py b/votify/interface/base.py index 5047b17..a0ef2fe 100644 --- a/votify/interface/base.py +++ b/votify/interface/base.py @@ -105,10 +105,19 @@ class SpotifyBaseInterface: def is_video(self, playback_info: dict) -> bool: return bool(playback_info["manifest"].get("manifest_ids_video")) - async def get_playback_info(self, media_id: str, media_type: str) -> dict | None: + async def get_playback_info( + self, + media_id: str, + media_type: str, + flac: bool = False, + ) -> dict | None: playback_info_response = await self.api.get_playback_info( media_id=media_id, media_type=media_type, + file_formats=[ + "manifest_ids_video", + "file_ids_mp4flac" if flac else "file_ids_mp4", + ], ) playback_info_key = next(iter(playback_info_response.get("media", {})), None) diff --git a/votify/interface/interface.py b/votify/interface/interface.py index 9007b19..1796019 100644 --- a/votify/interface/interface.py +++ b/votify/interface/interface.py @@ -5,7 +5,7 @@ from InquirerPy import inquirer from InquirerPy.base.control import Choice from .audio import SpotifyAudioInterface -from .enums import ArtistMediaOption +from .enums import ArtistMediaOption, AudioQuality from .episode import SpotifyEpisodeInterface from .episode_video import SpotifyEpisodeVideoInterface from .exceptions import ( @@ -61,6 +61,7 @@ class SpotifyInterface: playback_info = await self.base.get_playback_info( media_id=track_id, media_type="track", + flac=self.song.audio_quality == AudioQuality.FLAC, ) assert playback_info, "Playback info should be available for playable track"