Skip to content

Commit

Permalink
add deezer lyrics
Browse files Browse the repository at this point in the history
  • Loading branch information
topi314 committed Dec 25, 2023
1 parent 5511fb4 commit 1b9fa89
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 9 deletions.
1 change: 1 addition & 0 deletions main/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ java {

dependencies {
api "com.github.topi314.lavasearch:lavasearch:1.0.0"
api "com.github.topi314.lavalyrics:lavalyrics:c107309"
compileOnly "dev.arbjerg:lavaplayer:2.0.4"
implementation "org.jsoup:jsoup:1.15.3"
implementation "commons-io:commons-io:2.7"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.github.topi314.lavasrc.deezer;

import com.github.topi314.lavalyrics.AudioLyricsManager;
import com.github.topi314.lavalyrics.result.AudioLyrics;
import com.github.topi314.lavalyrics.result.BasicAudioLyrics;
import com.github.topi314.lavasearch.AudioSearchManager;
import com.github.topi314.lavasearch.result.AudioSearchResult;
import com.github.topi314.lavasearch.result.BasicAudioSearchResult;
Expand All @@ -26,6 +29,7 @@
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
Expand All @@ -37,7 +41,7 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class DeezerAudioSourceManager extends ExtendedAudioSourceManager implements HttpConfigurable, AudioSearchManager {
public class DeezerAudioSourceManager extends ExtendedAudioSourceManager implements HttpConfigurable, AudioSearchManager, AudioLyricsManager {

public static final Pattern URL_PATTERN = Pattern.compile("(https?://)?(www\\.)?deezer\\.com/(?<countrycode>[a-zA-Z]{2}/)?(?<type>track|album|playlist|artist)/(?<identifier>[0-9]+)");
public static final String SEARCH_PREFIX = "dzsearch:";
Expand All @@ -63,7 +67,7 @@ public DeezerAudioSourceManager(String masterDecryptionKey) {
this.httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager();
}

private void refreshSession() throws IOException{
private void refreshSession() throws IOException {
var getSessionID = new HttpPost(DeezerAudioSourceManager.PRIVATE_API_BASE + "?method=deezer.ping&input=3&api_version=1.0&api_token=");
var json = LavaSrcTools.fetchResponseAsJson(this.getHttpInterface(), getSessionID);

Expand All @@ -82,7 +86,7 @@ private void refreshSession() throws IOException{
);
}

public Tokens getTokens() throws IOException{
public Tokens getTokens() throws IOException {
if (this.tokens == null || Instant.now().isAfter(this.tokens.expireAt)) {
this.refreshSession();
}
Expand Down Expand Up @@ -120,6 +124,65 @@ public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input) throws
);
}

@Override
@Nullable
public AudioLyrics loadLyrics(@NotNull AudioTrack audioTrack) {
var deezerTackId = "";
if (audioTrack instanceof DeezerAudioTrack) {
deezerTackId = audioTrack.getInfo().identifier;
}

if (deezerTackId.isEmpty()) {
AudioItem item = AudioReference.NO_TRACK;
try {
if (audioTrack.getInfo().isrc != null && !audioTrack.getInfo().isrc.isEmpty()) {
item = this.getTrackByISRC(audioTrack.getInfo().isrc, false);
}
if (item == AudioReference.NO_TRACK) {
item = this.getSearch(String.format("%s %s", audioTrack.getInfo().title, audioTrack.getInfo().author), false);
}
} catch (IOException e) {
throw new RuntimeException(e);
}

if (item == AudioReference.NO_TRACK) {
return null;
}
if (item instanceof BasicAudioPlaylist) {
var playlist = (BasicAudioPlaylist) item;
if (!playlist.getTracks().isEmpty()) {
deezerTackId = playlist.getTracks().get(0).getIdentifier();
}
}
}

try {
return this.getLyrics(deezerTackId);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public AudioLyrics getLyrics(String id) throws IOException {
var json = this.getJson(PRIVATE_API_BASE + "?method=song.getLyrics&api_version=1.0&api_token=" + this.getTokens().api + "&sng_id=" + id);
if (json == null || json.get("results").values().isEmpty()) {
return null;
}

var results = json.get("results");
var lyricsText = results.get("LYRICS_TEXT").text();
var lyrics = new ArrayList<AudioLyrics.Line>();
for (var line : results.get("LYRICS_SYNC_JSON").values()) {
lyrics.add(new BasicAudioLyrics.BasicLine(
Duration.ofMillis(line.get("milliseconds").asLong(0)),
Duration.ofMillis(line.get("duration").asLong(0)),
line.get("line").text()
));
}

return new BasicAudioLyrics(lyricsText, lyrics);
}

@Override
@Nullable
public AudioSearchResult loadSearch(@NotNull String query, @NotNull Set<AudioSearchResult.Type> types) {
Expand Down Expand Up @@ -408,7 +471,7 @@ public static class Tokens {
public String license;
public Instant expireAt;

public Tokens(String api,String license, Instant expireAt) {
public Tokens(String api, String license, Instant expireAt) {
this.api = api;
this.license = license;
this.expireAt = expireAt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.sedmelluq.discord.lavaplayer.container.mp3.Mp3AudioTrack;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser;
import com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo;
Expand All @@ -20,7 +19,6 @@
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.stream.Collectors;

public class DeezerAudioTrack extends ExtendedAudioTrack {

Expand Down
6 changes: 4 additions & 2 deletions plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ plugins {
archivesBaseName = "lavasrc-plugin"
lavalinkPlugin {
name = "lavasrc-plugin"
apiVersion = "4.0.0"
serverVersion = "4.0.0"
apiVersion = gitHash("436763fe09b32fe26ee40cd238e3d1e910749cf9")
serverVersion = gitHash("436763fe09b32fe26ee40cd238e3d1e910749cf9")
configurePublishing = false
}

Expand All @@ -17,6 +17,8 @@ dependencies {
implementation project(":main")
compileOnly "com.github.topi314.lavasearch:lavasearch:1.0.0"
implementation "com.github.topi314.lavasearch:lavasearch-plugin-api:1.0.0"
compileOnly "com.github.topi314.lavalyrics:lavalyrics:c107309"
implementation "com.github.topi314.lavalyrics:lavalyrics-plugin-api:c107309"
}

publishing {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.topi314.lavasrc.plugin;

import com.github.topi314.lavalyrics.LyricsManager;
import com.github.topi314.lavalyrics.api.LyricsManagerConfiguration;
import com.github.topi314.lavasearch.SearchManager;
import com.github.topi314.lavasearch.api.SearchManagerConfiguration;
import com.github.topi314.lavasrc.applemusic.AppleMusicSourceManager;
Expand All @@ -17,7 +19,7 @@
import org.springframework.stereotype.Service;

@Service
public class LavaSrcPlugin implements AudioPlayerManagerConfiguration, SearchManagerConfiguration {
public class LavaSrcPlugin implements AudioPlayerManagerConfiguration, SearchManagerConfiguration, LyricsManagerConfiguration {

private static final Logger log = LoggerFactory.getLogger(LavaSrcPlugin.class);

Expand Down Expand Up @@ -133,4 +135,13 @@ public SearchManager configure(@NotNull SearchManager manager) {
return manager;
}

@NotNull
@Override
public LyricsManager configure(@NotNull LyricsManager manager) {
if (this.deezer != null) {
log.info("Registering Deezer lyrics manager...");
manager.registerLyricsManager(this.deezer);
}
return manager;
}
}

0 comments on commit 1b9fa89

Please sign in to comment.