deezer

package
v1.8.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package deezer is a Deezer client: ARL login, gw-light + public REST browse, and track -> CDN-url resolution. The ARL never leaves the machine beyond the requests it makes to Deezer.

Package deezer: Blowfish BF_CBC_STRIPE decryption for Deezer CDN streams.

Index

Constants

View Source
const (
	QualityNormal   = 0 // MP3 128
	QualityHigh     = 1 // MP3 320
	QualityLossless = 2 // FLAC (HiFi) — falls back to MP3 if unavailable
)

Quality levels.

Variables

View Source
var ErrARLExpired = errors.New("ARL expired or invalid — re-login required")

ErrARLExpired is returned by Login when the ARL cookie is missing/expired or otherwise rejected, so callers can distinguish "re-auth needed" from a transient network failure and prompt the user accordingly.

View Source
var ErrNoNetwork = errors.New("no internet connection")

ErrNoNetwork wraps any transport-level failure reaching Deezer (DNS failure, connection refused, host/network unreachable, TLS/dial timeout, context deadline). Callers use errors.Is(err, ErrNoNetwork) to show a "No Internet" screen and offer a retry, instead of mistaking an outage for an expired ARL (ErrARLExpired) and forcing the user to re-authenticate. The two are mutually exclusive: a reachable Deezer that rejects the ARL yields ErrARLExpired; an unreachable Deezer yields ErrNoNetwork.

Functions

func BlowfishKey

func BlowfishKey(trackID string) []byte

BlowfishKey derives the per-track Blowfish key: key[i] = md5hex[i] ^ md5hex[i+16] ^ secret[i].

func DecryptTrack

func DecryptTrack(trackID string, data []byte) ([]byte, error)

DecryptTrack decrypts a whole in-memory buffer (used by tests).

func FormatLabel

func FormatLabel(raw string) string

FormatLabel turns a raw Deezer media format into a human label for the UI.

func IsARLExpired added in v1.8.1

func IsARLExpired(err error) bool

IsARLExpired reports whether err is an expired/invalid-ARL auth failure.

func IsNoNetwork added in v1.8.1

func IsNoNetwork(err error) bool

IsNoNetwork reports whether err (or anything it wraps) is a transport-level connectivity failure. Exported for callers outside this package (the FFI bindings, the TUI) that classify a login/browse failure.

func TrackIDOf

func TrackIDOf(uri string) string

TrackIDOf extracts a numeric id from "deezer:track:123", a URL, or "123". Returns "" when no valid id is present.

Types

type Account added in v0.3.0

type Account struct {
	UserID   string `json:"userId"`
	Name     string `json:"name"`
	Offer    string `json:"offer"`
	CanHQ    bool   `json:"canHq"`   // entitled to MP3 320
	CanHiFi  bool   `json:"canHifi"` // entitled to lossless FLAC
	Premium  bool   `json:"premium"` // a paid plan that can stream on-demand
	LoggedIn bool   `json:"loggedIn"`
}

Account summarizes the logged-in user's plan and entitlements.

type Album

type Album struct {
	ID         string
	Name       string
	Artists    []Artist
	ArtworkURL string
}

Album is a search/browse result.

type Artist

type Artist struct {
	ID   string
	Name string
}

Artist is a track/album credit.

type ArtistInfo added in v0.3.0

type ArtistInfo struct {
	ID         string
	Name       string
	ArtworkURL string
	NbFans     int
}

ArtistInfo is an artist profile (search result / browse target).

type ArtistPage added in v0.3.0

type ArtistPage struct {
	Artist  ArtistInfo
	Top     []Track
	Albums  []Album
	Related []ArtistInfo
}

ArtistPage bundles an artist's profile with their top tracks, albums and related artists for a one-shot profile view.

type Chart added in v0.3.0

type Chart struct {
	Tracks    []Track
	Albums    []Album
	Artists   []ArtistInfo
	Playlists []Playlist
}

Chart is the global/genre top lists from the public REST /chart endpoint.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client holds an authenticated Deezer session.

func New

func New(arl string) *Client

New builds a client for the given ARL (not yet logged in).

func (*Client) Account added in v0.3.0

func (c *Client) Account() Account

Account returns the logged-in user's plan + entitlement summary.

func (*Client) AddFavoriteTrack added in v0.4.0

func (c *Client) AddFavoriteTrack(trackID string) error

AddFavoriteTrack likes a track (adds it to Liked Songs).

func (*Client) AddToPlaylist added in v0.4.0

func (c *Client) AddToPlaylist(playlistID, trackID string) error

AddToPlaylist appends a track to a playlist the user can edit.

func (*Client) AlbumTracks

func (c *Client) AlbumTracks(id string) ([]Track, error)

AlbumTracks lists an album's tracks via the public REST API.

func (*Client) ArtistProfile added in v0.3.0

func (c *Client) ArtistProfile(id string) (*ArtistPage, error)

ArtistProfile fetches an artist's profile plus top tracks, albums and related artists in one call (all public REST). A failure on any sub-list is tolerated so a partial profile still renders.

func (*Client) ArtistTop added in v0.3.0

func (c *Client) ArtistTop(id string) ([]Track, error)

ArtistTop lists an artist's most popular tracks (public REST).

func (*Client) Charts added in v0.3.0

func (c *Client) Charts(genreID string) (*Chart, error)

Charts fetches the global top tracks/albums/artists/playlists from the public REST /chart endpoint (no auth). Pass genreID "0" for the global chart.

func (*Client) CreatePlaylist added in v0.4.0

func (c *Client) CreatePlaylist(title string, trackIDs []string) (string, error)

CreatePlaylist creates a new playlist (optionally seeded with tracks) and returns its id.

func (*Client) DeletePlaylist added in v0.4.0

func (c *Client) DeletePlaylist(playlistID string) error

DeletePlaylist deletes a playlist the user owns.

func (*Client) EpisodeMeta added in v1.0.1

func (c *Client) EpisodeMeta(id string) (Episode, error)

EpisodeMeta fetches a single episode's metadata (title, podcast name, artwork) via the public REST /episode/{id} endpoint. Used to enrich now-playing after DZPlayEpisode (which only receives the id + duration from the caller).

func (*Client) Favorites

func (c *Client) Favorites() ([]Track, error)

Favorites lists the user's liked songs (gw).

func (*Client) Flow added in v0.4.0

func (c *Client) Flow() ([]Track, error)

Flow returns Deezer's personalized "Flow" radio: an endless, taste-based track stream. Uses the gw radio.getUserRadio method (community convention); needs live validation against a real account.

func (*Client) HighQuality

func (c *Client) HighQuality() bool

HighQuality reports whether the preference is at least MP3_320.

func (*Client) LoggedIn

func (c *Client) LoggedIn() bool

LoggedIn reports whether Login succeeded.

func (*Client) Login

func (c *Client) Login() error

Login authenticates and fetches api_token + license_token + sid + user id.

func (*Client) Lyrics added in v0.3.0

func (c *Client) Lyrics(trackID string) (*Lyrics, error)

Lyrics fetches a track's lyrics via gw song.getLyrics, returning both the plain text and, when Deezer provides them, time-synced lines.

func (*Client) PlaylistTracks

func (c *Client) PlaylistTracks(id string) ([]Track, error)

PlaylistTracks lists a playlist's tracks (gw, works for private playlists).

func (*Client) Playlists

func (c *Client) Playlists() ([]Playlist, error)

Playlists lists the user's own playlists (gw pageProfile).

func (*Client) PodcastEpisodeStream added in v0.4.0

func (c *Client) PodcastEpisodeStream(episodeID string) (*StreamPlan, error)

PodcastEpisodeStream resolves an episode to a plain (unencrypted) MP3 stream via gw episode.getData. The player decodes it directly (no Blowfish).

func (*Client) PodcastEpisodes added in v0.4.0

func (c *Client) PodcastEpisodes(podcastID string) ([]Episode, error)

PodcastEpisodes lists a show's episodes (public REST).

func (*Client) PrepareStream

func (c *Client) PrepareStream(trackID string) (*StreamPlan, error)

PrepareStream resolves a track id to a playable encrypted CDN URL.

func (*Client) Quality

func (c *Client) Quality() int

Quality returns the current preference (0..2).

func (*Client) RemoveFavoriteTrack added in v0.4.0

func (c *Client) RemoveFavoriteTrack(trackID string) error

RemoveFavoriteTrack unlikes a track.

func (*Client) RemoveFromPlaylist added in v0.4.0

func (c *Client) RemoveFromPlaylist(playlistID, trackID string) error

RemoveFromPlaylist removes a track from a playlist.

func (*Client) RenamePlaylist added in v0.4.0

func (c *Client) RenamePlaylist(playlistID, title string) error

RenamePlaylist changes a playlist's title.

func (*Client) Search

func (c *Client) Search(query string) (*SearchResults, error)

Search queries tracks, albums and playlists. A failing sub-search is tolerated as long as at least one succeeds; if all four fail, the first error is returned so callers can tell "no matches" from "request failed".

func (*Client) SearchPodcasts added in v0.4.0

func (c *Client) SearchPodcasts(query string) ([]Podcast, error)

SearchPodcasts finds shows via the public REST /search/podcast endpoint.

func (*Client) SetHighQuality

func (c *Client) SetHighQuality(high bool)

SetHighQuality keeps the old bool API: true => MP3_320, false => MP3_128.

func (*Client) SetQuality

func (c *Client) SetQuality(q int)

SetQuality selects the preferred stream quality (0..2). Deezer returns the first format the account+track is entitled to, so an unentitled FLAC/320 automatically falls back to a lower MP3 format.

func (*Client) Track added in v1.0.0

func (c *Client) Track(id string) (Track, error)

Track fetches a single track's metadata by id (gw song.getData). Used by the control API / MCP to "play track <id>".

func (*Client) UserID

func (c *Client) UserID() string

UserID returns the numeric Deezer user id (after Login).

type Episode added in v0.4.0

type Episode struct {
	ID          string
	Title       string
	Description string
	ArtworkURL  string
	DurationMS  int64
	ReleaseDate string
	PodcastName string
}

Episode is one podcast episode. Episodes stream as plain (unencrypted) MP3.

func (Episode) AsTrack added in v0.4.0

func (e Episode) AsTrack() Track

AsTrack adapts an episode to a Track so the existing queue/player/now-playing paths can carry it (episodes play via a plain StreamPlan).

type LyricLine added in v0.3.0

type LyricLine struct {
	TimeMS int64
	Text   string
}

LyricLine is one synced lyric line (TimeMS is the line's start offset).

type Lyrics added in v0.3.0

type Lyrics struct {
	Plain  string
	Synced []LyricLine
}

Lyrics holds a track's plain text plus, when available, time-synced lines.

func (Lyrics) IsSynced added in v0.3.0

func (l Lyrics) IsSynced() bool

IsSynced reports whether time-synced lyrics are present.

type Playlist

type Playlist struct {
	ID         string
	Name       string
	Owner      string
	TrackCount int
	ArtworkURL string
}

Playlist is a search/browse result.

type Podcast added in v0.4.0

type Podcast struct {
	ID           string
	Name         string
	Description  string
	ArtworkURL   string
	EpisodeCount int
}

Podcast is a show (search/browse result).

type SearchResults

type SearchResults struct {
	Tracks    []Track
	Albums    []Album
	Artists   []ArtistInfo
	Playlists []Playlist
}

SearchResults groups the searched entity kinds.

type StreamPlan

type StreamPlan struct {
	CDNURL    string
	TrackID   string
	Format    string
	GainDB    float64 // track ReplayGain in dB (0 if unknown)
	Encrypted bool    // false for plain CDN streams (e.g. podcast episodes)
}

StreamPlan is the resolved CDN URL + track id for decryption.

type StripeDecryptor

type StripeDecryptor struct {
	// contains filtered or unexported fields
}

StripeDecryptor streams BF_CBC_STRIPE plaintext out of ciphertext fed in arbitrary-sized pieces. Mirrors C++ DeezerStripeDecryptor.

func NewStripeDecryptor

func NewStripeDecryptor(trackID string) (*StripeDecryptor, error)

NewStripeDecryptor builds a decryptor keyed for trackID.

func (*StripeDecryptor) Feed

func (d *StripeDecryptor) Feed(data []byte, out []byte) []byte

Feed appends decrypted/passthrough output for n input bytes.

func (*StripeDecryptor) Finish

func (d *StripeDecryptor) Finish(out []byte) []byte

Finish flushes the trailing partial chunk (always plaintext).

type Track

type Track struct {
	ID         string
	Name       string
	DurationMS int64
	Artists    []Artist
	AlbumName  string
	ArtworkURL string
	Explicit   bool // explicit lyrics/content (show an "E" badge)
}

Track mirrors the C++ core::Track.

func (Track) ArtistLine

func (t Track) ArtistLine() string

ArtistLine joins artist names: "Artist A, Artist B".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL