diff --git a/README.md b/README.md index b4ac6efb..d8331cb0 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,319 @@ A collection of additional [Lavaplayer v2](https://github.com/sedmelluq/lavaplay ## Summary -* [Lavaplayer Usage](#lavaplayer-usage) * [Lavalink Usage](#lavalink-usage) + * [Configuration](#configuration) + * [Update Settings at Runtime](#update-settings-at-runtime) +* [Lavaplayer Usage](#lavaplayer-usage) * [Supported URLs and Queries](#supported-urls-and-queries) -## Lavaplayer Usage +## Lavalink Usage + +This plugin requires Lavalink `v4` or greater + +To install this plugin either download the latest release and place it into your `plugins` folder or add the following into your `application.yml` + +> [!Note] +> For a full `application.yml` example see [here](application.example.yml) Replace x.y.z with the latest version number -Snapshot builds are available in https://maven.topi.wtf/snapshots with the short commit hash as the version +```yaml +lavalink: + plugins: + - dependency: "com.github.topi314.lavasrc:lavasrc-plugin:x.y.z" + repository: "https://maven.lavalink.dev/releases" # this is optional for lavalink v4.0.0-beta.5 or greater + snapshot: false # set to true if you want to use snapshot builds (see below) +``` + +Snapshot builds are available in https://maven.lavalink.dev/snapshots with the short commit hash as the version + +### Configuration + +For all supported urls and queries see [here](#supported-urls-and-queries) + +To get your Spotify clientId, clientSecret go [here](https://developer.spotify.com/dashboard/applications) & then copy them into your `application.yml` like the following. + +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) + +To get your Vk Music user token go [here](#vk-music) + +> [!WARNING] +> YES `plugins` IS AT ROOT IN THE YAML + +```yaml +plugins: + lavasrc: + providers: # Custom providers for track loading. This is the default + # - "dzisrc:%ISRC%" # Deezer ISRC provider + # - "dzsearch:%QUERY%" # Deezer search provider + - "ytsearch:\"%ISRC%\"" # Will be ignored if track does not have an ISRC. See https://en.wikipedia.org/wiki/International_Standard_Recording_Code + - "ytsearch:%QUERY%" # Will be used if track has no ISRC or no track could be found for the ISRC + # you can add multiple other fallback sources here + sources: + spotify: false # Enable Spotify source + applemusic: false # Enable Apple Music source + deezer: false # Enable Deezer source + yandexmusic: false # Enable Yandex Music source + flowerytts: false # Enable Flowery TTS source + youtube: true # Enable YouTube search source (https://github.com/topi314/LavaSearch) + vkmusic: false # Enable Vk Music source + lyrics-sources: + spotify: false # Enable Spotify lyrics source + deezer: false # Enable Deezer lyrics source + youtube: false # Enable YouTube lyrics source + yandexmusic: false # Enable Yandex Music lyrics source + vkmusic: true # Enable Vk Music lyrics source + spotify: + clientId: "your client id" + clientSecret: "your client secret" + # spDc: "your sp dc cookie" # the sp dc cookie used for accessing the spotify lyrics api + countryCode: "US" # the country code you want to use for filtering the artists top tracks. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + playlistLoadLimit: 6 # The number of pages at 100 tracks each + albumLoadLimit: 6 # The number of pages at 50 tracks each + resolveArtistsInSearch: true # Whether to resolve artists in track search results (can be slow) + localFiles: false # Enable local files support with Spotify playlists. Please note `uri` & `isrc` will be `null` & `identifier` will be `"local"` + applemusic: + countryCode: "US" # the country code you want to use for filtering the artists top tracks and language. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + mediaAPIToken: "your apple music api token" # apple music api token + # or specify an apple music key + keyID: "your key id" + teamID: "your team id" + musicKitKey: | + -----BEGIN PRIVATE KEY----- + your key + -----END PRIVATE KEY----- + playlistLoadLimit: 6 # The number of pages at 300 tracks each + 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 this is optional but required for formats above MP3_128 + 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 + albumLoadLimit: 1 # The number of pages at 50 tracks each + artistLoadLimit: 1 # The number of pages at 10 tracks each + flowerytts: + voice: "default voice" # (case-sensitive) get default voice from here https://api.flowery.pw/v1/tts/voices + translate: false # whether to translate the text to the native language of voice + silence: 0 # the silence parameter is in milliseconds. Range is 0 to 10000. The default is 0. + speed: 1.0 # the speed parameter is a float between 0.5 and 10. The default is 1.0. (0.5 is half speed, 2.0 is double speed, etc.) + audioFormat: "mp3" # supported formats are: mp3, ogg_opus, ogg_vorbis, aac, wav, and flac. Default format is mp3 + youtube: + countryCode: "US" # the country code you want to use for searching lyrics via ISRC. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + vkmusic: + userToken: "your user token" # This token is needed for authorization in the api. Guide: https://github.com/topi314/LavaSrc#vk-music + playlistLoadLimit: 1 # The number of pages at 50 tracks each + artistLoadLimit: 1 # The number of pages at 10 tracks each + recommendationsLoadLimit: 10 # Number of tracks +``` + +### Plugin Info + +LavaSrc adds the following fields to tracks & playlists in Lavalink + +#### Track + +| Field | Type | Description | +|------------------|---------|--------------------------------| +| albumName | ?string | The name of the album | +| albumArtUrl | ?string | The url of the album art | +| artistUrl | ?string | The url of the artist | +| artistArtworkUrl | ?string | The url of the artist artwork | +| previewUrl | ?string | The url of the preview | +| isPreview | bool | Whether the track is a preview | + +
+Example Payload + +```json +{ + "encoded": "...", + "info": { + ... + }, + "pluginInfo": { + "albumName": "...", + "albumArtUrl": "...", + "artistUrl": "...", + "artistArtworkUrl": "...", + "previewUrl": "...", + "isPreview": false + }, + "userData": { + ... + } +} +``` + +
+ +#### Playlist + +| Field | Type | Description | +|-------------|----------------------------------|--------------------------------------------| +| type | [Playlist Type](#playlist-types) | The type of the playlist | +| url | ?string | The url of the playlist | +| artworkUrl | ?string | The url of the playlist artwork | +| author | ?string | The author of the playlist | +| totalTracks | ?int | The total number of tracks in the playlist | + +
+Example Payload + +```json +{ + "info": { + ... + }, + "pluginInfo": { + "type": "playlist", + "url": "...", + "artworkUrl": "...", + "author": "...", + "totalTracks": 10 + }, + "tracks": [ + ... + ] +} +``` + +
+ +#### Playlist Types + +| Type | Description | +|-------------------|--------------------------------------------| +| `album` | The playlist is an album | +| `playlist` | The playlist is a playlist | +| `artist` | The playlist is an artist | +| `recommendations` | The playlist is a recommendations playlist | + +--- + +### Update Settings at Runtime + +Sometimes you may want to update the settings at runtime without restarting Lavalink. This can be done by sending a `PATCH` request to the `/v4/lavasrc/config` endpoint. +Keep in mind this will **NOT** update the settings in the `application.yml` file. If you restart Lavalink the settings will be reset to the ones in the `application.yml` file. + +```http +PATCH /v4/lavasrc/config +``` + +#### LavaSrc Config Object + +> [!NOTE] +> All fields are optional and only the fields you provide will be updated. + +| Field | Type | Description | +|--------------|----------------------------------------------------|---------------------------| +| ?spotify | [Spotify Config](#spotify-config-object) | The Spotify settings | +| ?applemusic | [Apple Music Config](#apple-music-config-object) | The Apple Music settings | +| ?deezer | [Deezer Config](#deezer-config-object) | The Deezer settings | +| ?yandexMusic | [Yandex Music Config](#yandex-music-config-object) | The Yandex Music settings | +| ?vkMusic | [Vk Music Config](#vk-music-config-object) | The Vk Music settings | + +##### Spotify Config Object + +| Field | Type | Description | +|---------------|--------|--------------------------| +| ?clientId | string | The Spotify clientId | +| ?clientSecret | string | The Spotify clientSecret | +| ?spDc | string | The Spotify spDc cookie | + +##### Apple Music Config Object + +| Field | Type | Description | +|----------------|--------|---------------------------| +| ?mediaAPIToken | string | The Apple Music api token | + +##### Deezer Config Object + +| Field | Type | Description | +|----------|-------------------------------------------|-----------------------| +| ?arl | string | The Deezer arl cookie | +| ?formats | array of [Deezer Format](#deezer-formats) | The Deezer formats | + +##### Deezer Formats + +| Format | Description | +|-----------|-------------| +| `FLAC` | FLAC | +| `MP3_320` | MP3 320kbps | +| `MP3_256` | MP3 256kbps | +| `MP3_128` | MP3 128kbps | +| `MP3_64` | MP3 64kbps | +| `AAC_64` | AAC 64kbps | + +##### Yandex Music Config Object + +| Field | Type | Description | +|--------------|--------|-------------------------------| +| ?accessToken | string | The Yandex Music access token | + +##### Vk Music Config Object + +| Field | Type | Description | +|------------|--------|-------------------------| +| ?userToken | string | The Vk Music user token | + +
+Example Payload + +```json +{ + "spotify": { + "clientId": "your client id", + "clientSecret": "your client secret", + "spDc": "your sp dc cookie" + }, + "applemusic": { + "mediaAPIToken": "your apple music api token" + }, + "deezer": { + "arl": "your deezer arl", + "formats": [ + "FLAC", + "MP3_320", + "MP3_256", + "MP3_128", + "MP3_64", + "AAC_64" + ] + }, + "yandexMusic": { + "accessToken": "your access token" + }, + "vkMusic": { + "userToken": "your user token" + } +} +``` + +
+ +--- + + +## Lavaplayer Usage + +Replace `x.y.z` with the latest version number + +Snapshot builds are instead available in https://maven.topi.wtf/snapshots with the short commit hash as the version ### Using in Gradle:
Gradle -### ```gradle repositories { maven { @@ -47,6 +344,7 @@ dependencies { implementation "com.github.topi314.lavasrc:lavasrc-protocol:x.y.z" } ``` +
### Using in Maven: @@ -76,6 +374,7 @@ dependencies { ``` + --- @@ -93,7 +392,6 @@ To get a Spotify clientId & clientSecret you must go [here](https://developer.sp - ```java AudioPlayerManager playerManager = new DefaultAudioPlayerManager(); @@ -104,6 +402,7 @@ playerManager.registerSourceManager(spotify); ``` #### LavaLyrics +
Click to expand @@ -114,9 +413,11 @@ var lyricsManager = new LyricsManager(); // register source lyricsManager.registerLyricsManager(spotify); ``` +
#### LavaSearch +
Click to expand @@ -197,6 +498,7 @@ playerManager.registerSourceManager(deezer); ``` #### LavaLyrics +
Click to expand @@ -207,9 +509,11 @@ var lyricsManager = new LyricsManager(); // register source lyricsManager.registerLyricsManager(deezer); ``` +
#### LavaSearch +
Click to expand @@ -220,6 +524,7 @@ var searchManager = new SearchManager(); // register source searchManager.registerSearchManager(deezer); ``` +
--- @@ -239,7 +544,9 @@ searchManager.registerSearchManager(deezer); Token expires in 1 year. You can get a new one by repeating the steps above. #### Important information + Yandex Music is very location-dependent. You should either have a premium subscription or be located in one of the following countries: + - Azerbaijan - Armenia - Belarus @@ -265,6 +572,7 @@ playerManager.registerSourceManager(yandex); ``` #### LavaLyrics +
Click to expand @@ -275,9 +583,11 @@ var lyricsManager = new LyricsManager(); // register source lyricsManager.registerLyricsManager(yandex); ``` +
#### LavaSearch +
Click to expand @@ -288,6 +598,7 @@ var searchManager = new SearchManager(); // register source searchManager.registerSearchManager(yandex); ``` +
--- @@ -313,6 +624,7 @@ playerManager.registerSourceManager(new FloweryTTSSourceManager("...")); How to get user token ### WARNING! + #### Carefully, this token can be used to access your personal data. Use a newly created account specifically for LavaSrc. This source is designed mainly for the RU region, 80% of songs in other regions will not be played. 1. Go to the authorization page [Marusya application](https://oauth.vk.com/authorize?client_id=6463690&scope=1073737727&redirect_uri=https://oauth.vk.com/blank.html&display=page&response_type=token&revoke=1) @@ -330,6 +642,7 @@ playerManager.registerSourceManager(new VkMusicSourceManager("..."); ``` #### LavaLyrics +
Click to expand @@ -340,9 +653,11 @@ var lyricsManager = new LyricsManager(); // register source lyricsManager.registerLyricsManager(vkmusic); ``` +
#### LavaSearch +
Click to expand @@ -353,154 +668,15 @@ var searchManager = new SearchManager(); // register source searchManager.registerSearchManager(vkmusic); ``` -
- ---- - -## Lavalink Usage -This plugin requires Lavalink `v4` or greater - -To install this plugin either download the latest release and place it into your `plugins` folder or add the following into your `application.yml` - -> **Note** -> For a full `application.yml` example see [here](application.example.yml) - -Replace x.y.z with the latest version number -```yaml -lavalink: - plugins: - - dependency: "com.github.topi314.lavasrc:lavasrc-plugin:x.y.z" - repository: "https://maven.lavalink.dev/releases" # this is optional for lavalink v4.0.0-beta.5 or greater - snapshot: false # set to true if you want to use snapshot builds (see below) -``` - -Snapshot builds are available in https://maven.lavalink.dev/snapshots with the short commit hash as the version - -### Configuration - -For all supported urls and queries see [here](#supported-urls-and-queries) - -To get your Spotify clientId, clientSecret go [here](https://developer.spotify.com/dashboard/applications) & then copy them into your `application.yml` like the following. - -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) - -To get your Vk Music user token go [here](#vk-music) - -(YES `plugins` IS AT ROOT IN THE YAML) -```yaml -plugins: - lavasrc: - providers: # Custom providers for track loading. This is the default - # - "dzisrc:%ISRC%" # Deezer ISRC provider - # - "dzsearch:%QUERY%" # Deezer search provider - - "ytsearch:\"%ISRC%\"" # Will be ignored if track does not have an ISRC. See https://en.wikipedia.org/wiki/International_Standard_Recording_Code - - "ytsearch:%QUERY%" # Will be used if track has no ISRC or no track could be found for the ISRC - # you can add multiple other fallback sources here - sources: - spotify: false # Enable Spotify source - applemusic: false # Enable Apple Music source - deezer: false # Enable Deezer source - yandexmusic: false # Enable Yandex Music source - flowerytts: false # Enable Flowery TTS source - youtube: true # Enable YouTube search source (https://github.com/topi314/LavaSearch) - vkmusic: false # Enable Vk Music source - lyrics-sources: - spotify: false # Enable Spotify lyrics source - deezer: false # Enable Deezer lyrics source - youtube: false # Enable YouTube lyrics source - yandexmusic: false # Enable Yandex Music lyrics source - vkmusic: true # Enable Vk Music lyrics source - spotify: - clientId: "your client id" - clientSecret: "your client secret" - # spDc: "your sp dc cookie" # the sp dc cookie used for accessing the spotify lyrics api - countryCode: "US" # the country code you want to use for filtering the artists top tracks. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - playlistLoadLimit: 6 # The number of pages at 100 tracks each - albumLoadLimit: 6 # The number of pages at 50 tracks each - resolveArtistsInSearch: true # Whether to resolve artists in track search results (can be slow) - localFiles: false # Enable local files support with Spotify playlists. Please note `uri` & `isrc` will be `null` & `identifier` will be `"local"` - applemusic: - countryCode: "US" # the country code you want to use for filtering the artists top tracks and language. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - mediaAPIToken: "your apple music api token" # apple music api token - # or specify an apple music key - keyID: "your key id" - teamID: "your team id" - musicKitKey: | - -----BEGIN PRIVATE KEY----- - your key - -----END PRIVATE KEY----- - playlistLoadLimit: 6 # The number of pages at 300 tracks each - 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 this is optional but required for formats above MP3_128 - 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 - albumLoadLimit: 1 # The number of pages at 50 tracks each - artistLoadLimit: 1 # The number of pages at 10 tracks each - flowerytts: - voice: "default voice" # (case-sensitive) get default voice from here https://api.flowery.pw/v1/tts/voices - translate: false # whether to translate the text to the native language of voice - silence: 0 # the silence parameter is in milliseconds. Range is 0 to 10000. The default is 0. - speed: 1.0 # the speed parameter is a float between 0.5 and 10. The default is 1.0. (0.5 is half speed, 2.0 is double speed, etc.) - audioFormat: "mp3" # supported formats are: mp3, ogg_opus, ogg_vorbis, aac, wav, and flac. Default format is mp3 - youtube: - countryCode: "US" # the country code you want to use for searching lyrics via ISRC. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - vkmusic: - userToken: "your user token" # This token is needed for authorization in the api. Guide: https://github.com/topi314/LavaSrc#vk-music - playlistLoadLimit: 1 # The number of pages at 50 tracks each - artistLoadLimit: 1 # The number of pages at 10 tracks each - recommendationsLoadLimit: 10 # Number of tracks -``` - -### Plugin Info - -LavaSrc adds the following fields to tracks & playlists in Lavalink - -#### Track - -| Field | Type | Description | -|------------------|---------|--------------------------------| -| albumName | ?string | The name of the album | -| albumArtUrl | ?string | The url of the album art | -| artistUrl | ?string | The url of the artist | -| artistArtworkUrl | ?string | The url of the artist artwork | -| previewUrl | ?string | The url of the preview | -| isPreview | bool | Whether the track is a preview | - -#### Playlist - -| Field | Type | Description | -|-------------|----------------------------------|--------------------------------------------| -| type | [Playlist Type](#playlist-types) | The type of the playlist | -| url | ?string | The url of the playlist | -| artworkUrl | ?string | The url of the playlist artwork | -| author | ?string | The author of the playlist | -| totalTracks | ?int | The total number of tracks in the playlist | - -#### Playlist Types - -| Type | Description | -|-----------------|--------------------------------------------| -| album | The playlist is an album | -| playlist | The playlist is a playlist | -| artist | The playlist is an artist | -| recommendations | The playlist is a recommendations playlist | +
--- ## Supported URLs and Queries ### Spotify + * `spsearch:animals architects` (check out [Spotify Search Docs](https://developer.spotify.com/documentation/web-api/reference/search) for advanced search queries like isrc & co) * `sprec:seed_artists=3ZztVuWxHzNpl0THurTFCv,4MzJMcHQBl9SIYSjwWn8QW&seed_genres=metalcore&seed_tracks=5ofoB8PFmocBXFBEWVb6Vz,6I5zXzSDByTEmYZ7ePVQeB` (check out [Spotify Recommendations Docs](https://developer.spotify.com/documentation/web-api/reference/get-recommendations) for the full query parameter list) @@ -512,6 +688,7 @@ LavaSrc adds the following fields to tracks & playlists in Lavalink (including new regional links like https://open.spotify.com/intl-de/track/0eG08cBeKk0mzykKjw4hcQ) ### Apple Music + * `amsearch:animals architects` * https://music.apple.com/cy/album/animals/1533388849?i=1533388859 * https://music.apple.com/cy/album/for-those-that-wish-to-exist/1533388849 @@ -519,6 +696,7 @@ LavaSrc adds the following fields to tracks & playlists in Lavalink * https://music.apple.com/cy/artist/architects/182821355 ### Deezer + * `dzsearch:animals architects` * `dzisrc:USEP42058010` * https://deezer.page.link/U6BTQ2Q1KpmNt2yh8 @@ -528,6 +706,7 @@ LavaSrc adds the following fields to tracks & playlists in Lavalink * https://www.deezer.com/artist/159126 ### Yandex Music + * `ymsearch:animals architects` * `ymrec:71663565` (`ymrec:{TRACK_ID}`) * https://music.yandex.ru/album/13886032/track/71663565 @@ -537,12 +716,14 @@ LavaSrc adds the following fields to tracks & playlists in Lavalink * https://music.yandex.ru/artist/701626 ### Flowery TTS + You can read about all the available options [here](https://flowery.pw/docs), a list of available voices is [here](https://api.flowery.pw/v1/tts/voices) * `ftts://hello%20world` * `ftts://hello%20world?audio_format=ogg_opus&translate=False&silence=1000&speed=1.0&voice=09924826-684f-51e9-825b-cf85aed2b2cf` ### Vk Music + * `vksearch:animals architects` * `vkrec:-2001015907_104015907` (`vkrec:{TRACK_ID}`) * https://vk.com/audio-2001015907_104015907 @@ -557,4 +738,5 @@ You can read about all the available options [here](https://flowery.pw/docs), a * https://vk.com/music/album/-2000228258_15228258 * https://vk.com/audios700949584?q=phonk%20album&z=audio_playlist-2000933493_13933493%2Fbe3494d46d310b0d0d * https://vk.ru/audios700949584?q=phonk%20album&z=audio_playlist-2000933493_13933493 + --- diff --git a/main/src/main/java/com/github/topi314/lavasrc/applemusic/AppleMusicSourceManager.java b/main/src/main/java/com/github/topi314/lavasrc/applemusic/AppleMusicSourceManager.java index b7414445..d72951b6 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/applemusic/AppleMusicSourceManager.java +++ b/main/src/main/java/com/github/topi314/lavasrc/applemusic/AppleMusicSourceManager.java @@ -54,7 +54,7 @@ public class AppleMusicSourceManager extends MirroringAudioSourceManager impleme private final String countryCode; private int playlistPageLimit; private int albumPageLimit; - private final String token; + private String token; private String origin; private Instant tokenExpire; @@ -98,6 +98,15 @@ public void setAlbumPageLimit(int albumPageLimit) { this.albumPageLimit = albumPageLimit; } + public void setMediaAPIToken(String mediaAPIToken) { + this.token = mediaAPIToken; + try { + this.parseTokenData(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @NotNull @Override public String getSourceName() { diff --git a/main/src/main/java/com/github/topi314/lavasrc/deezer/DeezerAudioSourceManager.java b/main/src/main/java/com/github/topi314/lavasrc/deezer/DeezerAudioSourceManager.java index 0549046f..99c67627 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/deezer/DeezerAudioSourceManager.java +++ b/main/src/main/java/com/github/topi314/lavasrc/deezer/DeezerAudioSourceManager.java @@ -56,8 +56,8 @@ 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 String arl; + private DeezerAudioTrack.TrackFormat[] formats; private final HttpInterfaceManager httpInterfaceManager; private Tokens tokens; @@ -80,6 +80,17 @@ public DeezerAudioSourceManager(String masterDecryptionKey, @Nullable String arl this.httpInterfaceManager = HttpClientTools.createCookielessThreadLocalManager(); } + public void setFormats(DeezerAudioTrack.TrackFormat[] formats) { + if (formats.length == 0) { + throw new IllegalArgumentException("Deezer track formats must not be empty"); + } + this.formats = formats; + } + + public void setArl(String arl) { + this.arl = arl; + } + static void checkResponse(JsonBrowser json, String message) throws IllegalStateException { if (json == null) { throw new IllegalStateException(message + "No response"); diff --git a/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java b/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java index 0bf5ee3c..67300366 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java +++ b/main/src/main/java/com/github/topi314/lavasrc/spotify/SpotifySourceManager.java @@ -57,8 +57,8 @@ public class SpotifySourceManager extends MirroringAudioSourceManager implements private static final Logger log = LoggerFactory.getLogger(SpotifySourceManager.class); private final HttpInterfaceManager httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); - private final SpotifyTokenTracker tokenTracker; - private final String spDc; + private SpotifyTokenTracker tokenTracker; + private String spDc; private final String countryCode; private int playlistPageLimit = 6; private int albumPageLimit = 6; @@ -112,6 +112,16 @@ public void setResolveArtistsInSearch(boolean resolveArtistsInSearch) { this.resolveArtistsInSearch = resolveArtistsInSearch; } + public void setClientIDSecret(String clientId, String clientSecret) { + this.tokenTracker = new SpotifyTokenTracker(this, clientId, clientSecret); + } + + public void setSpDc(String spDc) { + this.spDc = spDc; + this.spToken = null; + this.spTokenExpire = null; + } + @NotNull @Override public String getSourceName() { @@ -365,7 +375,7 @@ public AudioItem getSearch(String query, boolean preview) throws IOException { } } - return new BasicAudioPlaylist("Search results for: " + query, this.parseTrackItems(json.get("tracks"), preview), null, true); + return new BasicAudioPlaylist("Spotify Search: " + query, this.parseTrackItems(json.get("tracks"), preview), null, true); } public AudioItem getRecommendations(String query, boolean preview) throws IOException { diff --git a/main/src/main/java/com/github/topi314/lavasrc/vkmusic/VkMusicSourceManager.java b/main/src/main/java/com/github/topi314/lavasrc/vkmusic/VkMusicSourceManager.java index 5d5cd788..95f0553b 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/vkmusic/VkMusicSourceManager.java +++ b/main/src/main/java/com/github/topi314/lavasrc/vkmusic/VkMusicSourceManager.java @@ -51,7 +51,7 @@ public class VkMusicSourceManager extends ExtendedAudioSourceManager implements private final HttpInterfaceManager httpInterfaceManager; - private final String userToken; + private String userToken; private int artistLoadLimit; private int playlistLoadLimit; private int recommendationsLoadLimit; @@ -64,6 +64,14 @@ public VkMusicSourceManager(String userToken) { this.httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); } + public void setUserToken(String userToken) { + if (userToken == null || userToken.isEmpty()) { + throw new IllegalArgumentException("Vk Music user token must be set"); + } + + this.userToken = userToken; + } + public void setArtistLoadLimit(int artistLimit) { this.artistLoadLimit = artistLimit; } @@ -426,11 +434,7 @@ private AudioItem getArtist(String id) throws IOException { } public JsonBrowser getJson(String method, String headers) throws IOException { - var uri = PUBLIC_API_BASE + method + "?v=" + API_VERSION + headers; - if (!this.userToken.isEmpty()) { - uri += "&access_token=" + this.userToken; - } - + var uri = PUBLIC_API_BASE + method + "?v=" + API_VERSION + headers + "&access_token=" + this.userToken; var request = new HttpGet(uri); request.setHeader("Content-Type", "application/json"); return LavaSrcTools.fetchResponseAsJson(this.httpInterfaceManager.getInterface(), request); diff --git a/main/src/main/java/com/github/topi314/lavasrc/yandexmusic/YandexMusicSourceManager.java b/main/src/main/java/com/github/topi314/lavasrc/yandexmusic/YandexMusicSourceManager.java index 16ac1cc0..e4ddc1b1 100644 --- a/main/src/main/java/com/github/topi314/lavasrc/yandexmusic/YandexMusicSourceManager.java +++ b/main/src/main/java/com/github/topi314/lavasrc/yandexmusic/YandexMusicSourceManager.java @@ -54,7 +54,7 @@ public class YandexMusicSourceManager extends ExtendedAudioSourceManager impleme private final HttpInterfaceManager httpInterfaceManager; - private final String accessToken; + private String accessToken; private int artistLoadLimit; private int albumLoadLimit; private int playlistLoadLimit; @@ -67,6 +67,13 @@ public YandexMusicSourceManager(String accessToken) { this.httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager(); } + public void setAccessToken(String accessToken) { + if (accessToken == null || accessToken.isEmpty()) { + throw new IllegalArgumentException("Yandex Music accessToken must be set"); + } + this.accessToken = accessToken; + } + public void setArtistLoadLimit(int artistLimit) { this.artistLoadLimit = artistLimit; } @@ -179,10 +186,6 @@ private AudioSearchResult getSearchResult(String query, Set setOfTypes) { - if (accessToken == null || accessToken.isEmpty()) { - throw new IllegalArgumentException("Yandex Music accessToken must be set"); - } - try { if (query.startsWith(SEARCH_PREFIX)) { return this.getSearchResult(query.substring(SEARCH_PREFIX.length()), setOfTypes); @@ -205,10 +208,6 @@ private JsonBrowser findLyrics(String identifier) throws IOException { @Override public @Nullable AudioLyrics loadLyrics(@NotNull AudioTrack track) throws IllegalStateException { - if (accessToken == null || accessToken.isEmpty()) { - throw new IllegalArgumentException("Yandex Music accessToken must be set"); - } - if (track.getSourceManager() instanceof YandexMusicSourceManager) { try { var lyricsJson = findLyrics(track.getIdentifier()); diff --git a/plugin/build.gradle b/plugin/build.gradle index 9f37f417..21f0fcf3 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -13,6 +13,7 @@ lavalinkPlugin { dependencies { implementation project(":main") + implementation project(":protocol") compileOnly "dev.lavalink.youtube:common:1.1.0" compileOnly "com.github.topi314.lavasearch:lavasearch:1.0.0" implementation "com.github.topi314.lavasearch:lavasearch-plugin-api:1.0.0" diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java index 7256f7a1..d7462a5d 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcPlugin.java @@ -6,8 +6,11 @@ import com.github.topi314.lavasearch.api.SearchManagerConfiguration; import com.github.topi314.lavasrc.applemusic.AppleMusicSourceManager; import com.github.topi314.lavasrc.deezer.DeezerAudioSourceManager; +import com.github.topi314.lavasrc.deezer.DeezerAudioTrack; import com.github.topi314.lavasrc.flowerytts.FloweryTTSSourceManager; import com.github.topi314.lavasrc.mirror.DefaultMirroringAudioTrackResolver; +import com.github.topi314.lavasrc.plugin.config.*; +import com.github.topi314.lavasrc.protocol.Config; import com.github.topi314.lavasrc.spotify.SpotifySourceManager; import com.github.topi314.lavasrc.vkmusic.VkMusicSourceManager; import com.github.topi314.lavasrc.yandexmusic.YandexMusicSourceManager; @@ -18,8 +21,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.RestController; @Service +@RestController public class LavaSrcPlugin implements AudioPlayerManagerConfiguration, SearchManagerConfiguration, LyricsManagerConfiguration { private static final Logger log = LoggerFactory.getLogger(LavaSrcPlugin.class); @@ -211,4 +217,51 @@ public LyricsManager configure(@NotNull LyricsManager manager) { } return manager; } + + @PatchMapping("/v4/lavasrc/config") + public void updateConfig(Config config) { + var spotifyConfig = config.getSpotify(); + if (spotifyConfig != null && this.spotify != null) { + if (spotifyConfig.getSpDc() != null) { + this.spotify.setSpDc(spotifyConfig.getSpDc()); + } + if (spotifyConfig.getClientId() != null && spotifyConfig.getClientSecret() != null) { + this.spotify.setClientIDSecret(spotifyConfig.getClientId(), spotifyConfig.getClientSecret()); + } + } + + var appleMusicConfig = config.getAppleMusic(); + if (appleMusicConfig != null && this.appleMusic != null && appleMusicConfig.getMediaAPIToken() != null) { + this.appleMusic.setMediaAPIToken(appleMusicConfig.getMediaAPIToken()); + } + + var deezerConfig = config.getDeezer(); + if (deezerConfig != null && this.deezer != null) { + if (deezerConfig.getArl() != null) { + this.deezer.setArl(deezerConfig.getArl()); + } + if (deezerConfig.getFormats() != null) { + this.deezer.setFormats(deezerConfig.getFormats() + .stream() + .map(deezerTrackFormat -> DeezerAudioTrack.TrackFormat.from(deezerTrackFormat.name())) + .toList() + .toArray(new DeezerAudioTrack.TrackFormat[0]) + ); + } + } + + var yandexMusicConfig = config.getYandexMusic(); + if (yandexMusicConfig != null && this.yandexMusic != null) { + if (yandexMusicConfig.getAccessToken() != null) { + this.yandexMusic.setAccessToken(yandexMusicConfig.getAccessToken()); + } + } + + var vkMusicConfig = config.getVkMusic(); + if (vkMusicConfig != null && this.vkMusic != null) { + if (vkMusicConfig.getUserToken() != null) { + this.vkMusic.setUserToken(vkMusicConfig.getUserToken()); + } + } + } } diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/AppleMusicConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/AppleMusicConfig.java similarity index 96% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/AppleMusicConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/AppleMusicConfig.java index d50c8f55..718a44de 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/AppleMusicConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/AppleMusicConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/DeezerConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/DeezerConfig.java similarity index 94% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/DeezerConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/DeezerConfig.java index 806dcd47..7d283aca 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/DeezerConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/DeezerConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import com.github.topi314.lavasrc.deezer.DeezerAudioTrack; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/FloweryTTSConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/FloweryTTSConfig.java similarity index 91% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/FloweryTTSConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/FloweryTTSConfig.java index c71d2a0e..8212a548 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/FloweryTTSConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/FloweryTTSConfig.java @@ -1,55 +1,55 @@ -package com.github.topi314.lavasrc.plugin; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -@ConfigurationProperties(prefix = "plugins.lavasrc.flowerytts") -@Component -public class FloweryTTSConfig { - - private String voice = null; - private boolean translate; - private int silence; - private float speed = 1.0F; - private String audioFormat = "mp3"; - - public String getVoice() { - return this.voice; - } - - public void setVoice(String voice) { - this.voice = voice; - } - - public boolean getTranslate() { - return this.translate; - } - - public void setTranslate(boolean translate) { - this.translate = translate; - } - - public int getSilence() { - return this.silence; - } - - public void setSilence(int silence) { - this.silence = silence; - } - - public float getSpeed() { - return this.speed; - } - - public void setSpeed(float speed) { - this.speed = speed; - } - - public String getAudioFormat() { - return this.audioFormat; - } - - public void setAudioFormat(String audioFormat) { - this.audioFormat = audioFormat; - } +package com.github.topi314.lavasrc.plugin.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@ConfigurationProperties(prefix = "plugins.lavasrc.flowerytts") +@Component +public class FloweryTTSConfig { + + private String voice = null; + private boolean translate; + private int silence; + private float speed = 1.0F; + private String audioFormat = "mp3"; + + public String getVoice() { + return this.voice; + } + + public void setVoice(String voice) { + this.voice = voice; + } + + public boolean getTranslate() { + return this.translate; + } + + public void setTranslate(boolean translate) { + this.translate = translate; + } + + public int getSilence() { + return this.silence; + } + + public void setSilence(int silence) { + this.silence = silence; + } + + public float getSpeed() { + return this.speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + public String getAudioFormat() { + return this.audioFormat; + } + + public void setAudioFormat(String audioFormat) { + this.audioFormat = audioFormat; + } } \ No newline at end of file diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/LavaSrcConfig.java similarity index 92% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/LavaSrcConfig.java index 929a520d..0102a72c 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LavaSrcConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/LavaSrcConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LyricsSourcesConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/LyricsSourcesConfig.java similarity index 95% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/LyricsSourcesConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/LyricsSourcesConfig.java index 1d75b888..6d64ac28 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/LyricsSourcesConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/LyricsSourcesConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SourcesConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/SourcesConfig.java similarity index 96% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/SourcesConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/SourcesConfig.java index 1b21f76e..f9780955 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SourcesConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/SourcesConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/SpotifyConfig.java similarity index 97% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/SpotifyConfig.java index 6f85913e..62a926d0 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/SpotifyConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/SpotifyConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/VkMusicConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/VkMusicConfig.java similarity index 95% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/VkMusicConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/VkMusicConfig.java index f13b74e5..14db712f 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/VkMusicConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/VkMusicConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/YandexMusicConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/YandexMusicConfig.java similarity index 95% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/YandexMusicConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/YandexMusicConfig.java index d68b91bf..5ddb7471 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/YandexMusicConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/YandexMusicConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/YouTubeConfig.java b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/YouTubeConfig.java similarity index 89% rename from plugin/src/main/java/com/github/topi314/lavasrc/plugin/YouTubeConfig.java rename to plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/YouTubeConfig.java index d4262ef3..7ac89b23 100644 --- a/plugin/src/main/java/com/github/topi314/lavasrc/plugin/YouTubeConfig.java +++ b/plugin/src/main/java/com/github/topi314/lavasrc/plugin/config/YouTubeConfig.java @@ -1,4 +1,4 @@ -package com.github.topi314.lavasrc.plugin; +package com.github.topi314.lavasrc.plugin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/protocol/src/commonMain/kotlin/com/github/topi314/lavasrc/protocol/Config.kt b/protocol/src/commonMain/kotlin/com/github/topi314/lavasrc/protocol/Config.kt new file mode 100644 index 00000000..70e2cbd3 --- /dev/null +++ b/protocol/src/commonMain/kotlin/com/github/topi314/lavasrc/protocol/Config.kt @@ -0,0 +1,51 @@ +package com.github.topi314.lavasrc.protocol + +import kotlinx.serialization.Serializable + +@Serializable +data class Config( + val spotify: SpotifyConfig? = null, + val appleMusic: AppleMusicConfig? = null, + val deezer: DeezerConfig? = null, + val yandexMusic: YandexMusicConfig? = null, + val vkMusic: VkMusicConfig? = null, +) + +@Serializable +data class SpotifyConfig( + val clientId: String? = null, + val clientSecret: String? = null, + val spDc: String? = null, +) + +@Serializable +data class AppleMusicConfig( + val mediaAPIToken: String? = null, +) + +@Serializable +data class DeezerConfig( + val arl: String? = null, + val formats: List? = null, +) + +@Suppress("unused") +@Serializable +enum class DeezerTrackFormat { + FLAC, + MP3_320, + MP3_256, + MP3_128, + MP3_64, + AAC_64 +} + +@Serializable +data class YandexMusicConfig( + val accessToken: String? = null, +) + +@Serializable +data class VkMusicConfig( + val userToken: String? = null, +) \ No newline at end of file