Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions streamrip/client/deezer.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,38 @@ async def get_track(self, item_id: str) -> dict:
album_metadata["track_total"] = len(album_tracks["data"])
item["album"] = album_metadata

if self.global_config.session.downloads.lyrics:
try:
lyrics_resp = await asyncio.to_thread(
self.client.gw.get_track_lyrics, item_id
)
# Use unsynced lyrics for MP3, synced for others (FLAC, OPUS, etc)
conversion = self.global_config.session.conversion
if conversion.enabled and conversion.codec.upper() == "MP3":
item["lyrics"] = lyrics_resp.get("LYRICS_TEXT") or ""
else:
item["lyrics"] = self._format_synced_lyrics(
lyrics_resp.get("LYRICS_SYNC_JSON")
) or (lyrics_resp.get("LYRICS_TEXT") or "")
except Exception as e:
logger.warning(f"Failed to get lyrics for {item_id}: {e}")

return item

@staticmethod
def _format_synced_lyrics(sync_json: list[dict] | None) -> str:
"""Convert Deezer's LYRICS_SYNC_JSON into LRC-formatted text."""
if not sync_json:
return ""
lines = []
for entry in sync_json:
timestamp = entry.get("lrc_timestamp")
if timestamp:
lines.append(f"{timestamp}{entry.get('line', '')}")
else:
lines.append("")
return "\n".join(lines)

async def get_album(self, item_id: str) -> dict:
album_metadata, album_tracks = await asyncio.gather(
asyncio.to_thread(self.client.api.get_album, item_id),
Expand Down
2 changes: 1 addition & 1 deletion streamrip/client/tidal.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ async def get_metadata(self, item_id: str, media_type: str) -> dict:

item["albums"] = album_resp["items"]
item["albums"].extend(ep_resp["items"])
elif media_type == "track":
elif media_type == "track" and self.global_config.session.downloads.lyrics:
try:
resp = await self._api_request(
f"tracks/{item_id!s}/lyrics", base="https://tidal.com/v1"
Expand Down
3 changes: 3 additions & 0 deletions streamrip/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ class DownloadsConfig:
# Verify SSL certificates for API connections
# Set to false if you encounter SSL certificate verification errors (not recommended)
verify_ssl: bool
# Download and embed lyrics (currently supported for Deezer and Tidal)
# Defaulted so configs written before this option don't fail to load
lyrics: bool = True


@dataclass(slots=True)
Expand Down
2 changes: 2 additions & 0 deletions streamrip/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ requests_per_minute = 60
# Verify SSL certificates for API connections
# Set to false if you encounter SSL certificate verification errors (not recommended)
verify_ssl = true
# Download and embed lyrics (currently supported for Deezer and Tidal)
lyrics = true

[qobuz]
# 1: 320kbps MP3, 2: 16/44.1, 3: 24/<=96, 4: 24/>=96
Expand Down
2 changes: 2 additions & 0 deletions streamrip/metadata/track.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def from_deezer(cls, album: AlbumMetadata, resp) -> TrackMetadata | None:
tracknumber = typed(resp["track_position"], int)
discnumber = typed(resp["disk_number"], int)
composer = None
lyrics = resp.get("lyrics", "")
info = TrackInfo(
id=track_id,
quality=album.info.quality,
Expand All @@ -116,6 +117,7 @@ def from_deezer(cls, album: AlbumMetadata, resp) -> TrackMetadata | None:
discnumber=discnumber,
composer=composer,
isrc=isrc,
lyrics=lyrics,
)

@classmethod
Expand Down
1 change: 1 addition & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def test_sample_config_data_fields(sample_config_data):
max_connections=6,
requests_per_minute=60,
verify_ssl=True,
lyrics=True,
),
qobuz=QobuzConfig(
use_auth_token=False,
Expand Down
2 changes: 2 additions & 0 deletions tests/test_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ requests_per_minute = 60
# Verify SSL certificates for API connections
# Set to false if you encounter SSL certificate verification errors (not recommended)
verify_ssl = true
# Download and embed lyrics (currently supported for Deezer and Tidal)
lyrics = true

[qobuz]
# 1: 320kbps MP3, 2: 16/44.1, 3: 24/<=96, 4: 24/>=96
Expand Down