Skip to content

Commit

Permalink
Add support for FLAC streaming. (#178) (#179)
Browse files Browse the repository at this point in the history
* Add support for FLAC streaming. (#178)

* Make some methods public for legal reasons :) (#185)

* Update DeezerAudioTrack.java

* fix deezer arl support

---------

Co-authored-by: devoxin <15076404+devoxin@users.noreply.github.com>
Co-authored-by: Duncan Sterken <contact@duncte123.me>
  • Loading branch information
3 people committed Aug 20, 2024
1 parent bfd5b47 commit e360324
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 60 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,25 @@ AudioPlayerManager playerManager = new DefaultAudioPlayerManager();

// create a new DeezerSourceManager with the master decryption key and register it

var deezer = new DeezerSourceManager("...");
var deezer = new DeezerSourceManager("the master decryption key", "your arl", formats);
playerManager.registerSourceManager(deezer);
```

<details>
<summary>How to get deezer master decryption key</summary>

Use google.

</details>

<details>
<summary>How to get deezer arl cookie</summary>

Use google to find a guide on how to get the arl cookie. It's not that hard.

</details>


#### LavaLyrics
<details>
<summary>Click to expand</summary>
Expand Down Expand Up @@ -312,6 +327,8 @@ To get your Spotify spDc cookie go [here](#spotify)

To get your Apple Music api token go [here](#apple-music)

To get your Deezer arl cookie go [here](#deezer)

To get your Yandex Music access token go [here](#yandex-music)

(YES `plugins` IS AT ROOT IN THE YAML)
Expand Down Expand Up @@ -358,6 +375,8 @@ plugins:
albumLoadLimit: 6 # The number of pages at 300 tracks each
deezer:
masterDecryptionKey: "your master decryption key" # the master key used for decrypting the deezer tracks. (yes this is not here you need to get it from somewhere else)
arl: "your deezer arl" # the arl cookie used for accessing the deezer api
formats: [ "FLAC", "MP3_320", "MP3_256", "MP3_128", "MP3_64", "AAC_64" ] # the formats you want to use for the deezer tracks. "FLAC", "MP3_320", "MP3_256" & "AAC_64" are only available for premium users and require a valid arl
yandexmusic:
accessToken: "your access token" # the token used for accessing the yandex music api. See https://github.com/TopiSenpai/LavaSrc#yandex-music
playlistLoadLimit: 1 # The number of pages at 100 tracks each
Expand Down
2 changes: 2 additions & 0 deletions application.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ plugins:
albumLoadLimit: 6 # The number of pages at 300 tracks each
deezer:
masterDecryptionKey: "your master decryption key" # the master key used for decrypting the deezer tracks. (yes this is not here you need to get it from somewhere else)
arl: "your deezer arl" # the arl cookie used for accessing the deezer api
formats: [ "FLAC", "MP3_320", "MP3_256", "MP3_128", "MP3_64", "AAC_64" ] # the formats you want to use for the deezer tracks. "FLAC", "MP3_320", "MP3_256" & "AAC_64" are only available for premium users and require a valid arl
yandexmusic:
accessToken: "your access token" # the token used for accessing the yandex music api. See https://github.com/TopiSenpai/LavaSrc#yandex-music
playlistLoadLimit: 1 # The number of pages at 100 tracks each
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,39 @@ public class DeezerAudioSourceManager extends ExtendedAudioSourceManager impleme
private static final Logger log = LoggerFactory.getLogger(DeezerAudioSourceManager.class);

private final String masterDecryptionKey;
private final String arl;
private final DeezerAudioTrack.TrackFormat[] formats;
private final HttpInterfaceManager httpInterfaceManager;
private Tokens tokens;

public DeezerAudioSourceManager(String masterDecryptionKey) {
this(masterDecryptionKey, null);
}

public DeezerAudioSourceManager(String masterDecryptionKey, @Nullable String arl) {
this(masterDecryptionKey, arl, null);
}

public DeezerAudioSourceManager(String masterDecryptionKey, @Nullable String arl, @Nullable DeezerAudioTrack.TrackFormat[] formats) {
if (masterDecryptionKey == null || masterDecryptionKey.isEmpty()) {
throw new IllegalArgumentException("Deezer master key must be set");
}

this.masterDecryptionKey = masterDecryptionKey;
this.httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager();
this.arl = arl != null && arl.isEmpty() ? null : arl;
this.formats = formats != null && formats.length > 0 ? formats : DeezerAudioTrack.TrackFormat.DEFAULT_FORMATS;
this.httpInterfaceManager = HttpClientTools.createCookielessThreadLocalManager();
}

static void checkResponse(JsonBrowser json, String message) throws IllegalStateException {
if (json == null) {
throw new IllegalStateException(message + "No response");
}
var errors = json.get("data").index(0).get("errors").values();
if (!errors.isEmpty()) {
var errorsStr = errors.stream().map(error -> error.get("code").text() + ": " + error.get("message").text()).collect(Collectors.joining(", "));
throw new IllegalStateException(message + errorsStr);
}
}

private void refreshSession() throws IOException {
Expand Down Expand Up @@ -93,17 +117,6 @@ public Tokens getTokens() throws IOException {
return this.tokens;
}

static void checkResponse(JsonBrowser json, String message) throws IllegalStateException {
if (json == null) {
throw new IllegalStateException(message + "No response");
}
var errors = json.get("data").index(0).get("errors").values();
if (!errors.isEmpty()) {
var errorsStr = errors.stream().map(error -> error.get("code").text() + ": " + error.get("message").text()).collect(Collectors.joining(", "));
throw new IllegalStateException(message + errorsStr);
}
}

@NotNull
@Override
public String getSourceName() {
Expand Down Expand Up @@ -398,12 +411,12 @@ private AudioItem getAlbum(String id, boolean preview) throws IOException {
}

return new DeezerAudioPlaylist(json.get("title").text(),
this.parseTracks(tracks, preview),
DeezerAudioPlaylist.Type.ALBUM,
json.get("link").text(),
artworkUrl,
author,
(int) json.get("nb_tracks").asLong(0));
this.parseTracks(tracks, preview),
DeezerAudioPlaylist.Type.ALBUM,
json.get("link").text(),
artworkUrl,
author,
(int) json.get("nb_tracks").asLong(0));
}

private AudioItem getTrack(String id, boolean preview) throws IOException {
Expand All @@ -427,12 +440,12 @@ private AudioItem getPlaylist(String id, boolean preview) throws IOException {
var tracks = this.getJson(PUBLIC_API_BASE + "/playlist/" + id + "/tracks?limit=10000");

return new DeezerAudioPlaylist(json.get("title").text(),
this.parseTracks(tracks, preview),
DeezerAudioPlaylist.Type.PLAYLIST,
json.get("link").text(),
artworkUrl,
author,
(int) json.get("nb_tracks").asLong(0));
this.parseTracks(tracks, preview),
DeezerAudioPlaylist.Type.PLAYLIST,
json.get("link").text(),
artworkUrl,
author,
(int) json.get("nb_tracks").asLong(0));
}

private AudioItem getArtist(String id, boolean preview) throws IOException {
Expand Down Expand Up @@ -479,6 +492,15 @@ public String getMasterDecryptionKey() {
return this.masterDecryptionKey;
}

@Nullable
public String getArl() {
return this.arl;
}

public DeezerAudioTrack.TrackFormat[] getFormats() {
return this.formats;
}

public HttpInterface getHttpInterface() {
return this.httpInterfaceManager.getInterface();
}
Expand Down
Loading

0 comments on commit e360324

Please sign in to comment.