You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+91Lines changed: 91 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,3 +45,94 @@ After modifying the `.proto` files you need to, **make sure to follow [these ste
45
45
46
46
- Commit both the source`.proto` and the regenerated Python output **together** so they can
47
47
be compared easily.
48
+
49
+
## Architecture
50
+
51
+
The main components are:
52
+
53
+
- **`Session` class***(entrypoint)*
54
+
55
+
- `Session.Builder` is used to configure and create a session, via one of:
56
+
57
+
- username/password
58
+
- stored credentials
59
+
- OAuth
60
+
61
+
- An active session is **required**for all other operations.
62
+
63
+
- **`ApiClient` class**
64
+
65
+
- A high-level client for making standard HTTPS requests to Spotify's Web API endpoints (e.g., `https://spclient.wg.spotify.com`).
66
+
- Accessed via `session.api()`, it provides convenient methods like `get_metadata_4_track()` and handles client tokens automatically.
67
+
68
+
- **`MercuryClient` class**
69
+
70
+
- The low-level client for Spotify's proprietary `mercury` protocol, which uses `hm://` URIs.
71
+
- Accessed via `session.mercury()`, it handles sending and receiving messages over the main session connection for metadata lookups and subscriptions that are not available via the standard Web API.
72
+
73
+
- **`DealerClient` class**
74
+
75
+
- Manages the persistent WebSocket (`wss://`) connection to Spotify's `dealer` service.
76
+
- Accessed via `session.dealer()`, it listens for and dispatches real-time, asynchronous JSON-based events, such as remote player state changes or notifications from other connected devices.
77
+
78
+
- **`Session.Receiver` thread**
79
+
80
+
- Spawned after authentication to read every encrypted packet coming from the access point.
81
+
- Routes decoded commands to subsystems (`MercuryClient`, `AudioKeyManager`, `ChannelManager`, etc.) and responds to keep-alive pings to hold the session open.
82
+
83
+
- **Metadata types**
84
+
85
+
- The `librespot.metadata` module provides typed identifiers (`TrackId`, `AlbumId`, `PlaylistId`, `EpisodeId`, etc.) used to reference Spotify content throughout the API.
86
+
- They are constructed from Spotify identifiers, typically using one of the following methods:
87
+
88
+
- `from_uri()`: For all ID types.
89
+
- `from_base62()`: For most ID types (e.g., tracks, albums, artists).
90
+
91
+
- **`PlayableContentFeeder` class**
92
+
93
+
- Retrieves audio streams; is accessed via `session.content_feeder()`.
- an optional `HaltListener` callback (pass `None` if unneeded).
102
+
103
+
- Returns a `LoadedStream` that contains the decrypted stream together with:
104
+
105
+
- track/episode metadata
106
+
- normalization data
107
+
- transfer metrics
108
+
109
+
- **`audio` module**
110
+
111
+
- Contains tools for format selection, quality management, streaming, and decryption.
112
+
- `VorbisOnlyAudioQuality` and `LosslessOnlyAudioQuality` choose the best matching `Metadata.AudioFile` for a preferred container/quality combination.
113
+
- `CdnManager` acquires and refreshes signed CDN URLs, feeding a `Streamer` that decrypts chunks on the fly while staying seekable.
114
+
115
+
- **`AudioKeyManager` and `ChannelManager`**
116
+
117
+
- Handle the low-level transport for protected audio: `AudioKeyManager` requests AES keys, and `ChannelManager` can stream encrypted chunks directly from the access point when CDN delivery is unavailable.
118
+
- Both are driven transparently by `PlayableContentFeeder`/`CdnManager`, so callers only interact with the decrypted `LoadedStream`.
119
+
120
+
- **`EventService` class**
121
+
122
+
- Asynchronous publisher that emits telemetry (e.g., fetch metrics, playback events) to `hm://event-service/v1/events` via Mercury.
123
+
- Accessible through `session.event_service()` for consumers that need to forward custom events.
124
+
125
+
- **`TokenProvider` class**
126
+
127
+
- Caches Login5 access tokens per scope, refreshing them proactively as they near expiry.
128
+
- Used by `ApiClient` to supply the correct `Authorization` headers for Spotify Web API calls.
129
+
130
+
- **`SearchManager` class**
131
+
132
+
- High-level wrapper around `hm://searchview/km/v4/search/...` requests sent over Mercury.
133
+
- Fills in username, locale, and country defaults from the current session before dispatching the call.
134
+
135
+
- **OAuth tokens for Spotify Web API**
136
+
137
+
- Can be obtained via `session.tokens().get(scope)`
138
+
- Enable authenticated API calls for operations like search, playlist management, and user data access
0 commit comments