Skip to content

Commit

Permalink
Update TidalSourceManager.java
Browse files Browse the repository at this point in the history
  • Loading branch information
Nansess authored Apr 18, 2024
1 parent ffa4c6f commit 3151b3f
Showing 1 changed file with 69 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,44 +38,36 @@ public class TidalSourceManager
implements HttpConfigurable {

public static final Pattern URL_PATTERN = Pattern.compile(
"https?://(?:(?:listen|www)\\.)?tidal\\.com/(?:browse/)?(?<type>album|track|playlist)/(?<id>[a-zA-Z0-9\\-]+)(?:\\?.*)?"
);

"https?://(?:(?:listen|www)\\.)?tidal\\.com/(?:browse/)?(?<type>album|track|playlist)/(?<id>[a-zA-Z0-9\\-]+)(?:\\?.*)?");

public static final String SEARCH_PREFIX = "tdsearch:";
public static final String PUBLIC_API_BASE = "https://api.tidal.com/v1/";
public static final int PLAYLIST_MAX_PAGE_ITEMS = 750;
public static final int ALBUM_MAX_PAGE_ITEMS = 120;
private static final String USER_AGENT =
"TIDAL/3704 CFNetwork/1220.1 Darwin/20.3.0";
private static final String USER_AGENT = "TIDAL/3704 CFNetwork/1220.1 Darwin/20.3.0";
private static final String TIDAL_TOKEN = "i4ZDjcyhed7Mu47q";

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

private final HttpInterfaceManager httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager();
private int searchLimit = 6;
private final String countryCode;


public TidalSourceManager(
String[] providers,
String countryCode,
Function<Void, AudioPlayerManager> audioPlayerManager
) {
Function<Void, AudioPlayerManager> audioPlayerManager) {
this(
countryCode,
audioPlayerManager,
new DefaultMirroringAudioTrackResolver(providers)
);
new DefaultMirroringAudioTrackResolver(providers));
}

public TidalSourceManager(
String countryCode,
Function<Void, AudioPlayerManager> audioPlayerManager,
MirroringAudioTrackResolver mirroringAudioTrackResolver
) {
MirroringAudioTrackResolver mirroringAudioTrackResolver) {
super(audioPlayerManager, mirroringAudioTrackResolver);
if (countryCode == null || countryCode.isEmpty()) {
countryCode = "US";
Expand Down Expand Up @@ -104,15 +96,13 @@ public AudioTrack decodeTrack(AudioTrackInfo trackInfo, DataInput input)
extendedAudioTrackInfo.artistArtworkUrl,
extendedAudioTrackInfo.previewUrl,
extendedAudioTrackInfo.isPreview,
this
);
this);
}

@Override
public AudioItem loadItem(
AudioPlayerManager manager,
AudioReference reference
) {
AudioReference reference) {
try {
var identifier = reference.identifier;
var matcher = URL_PATTERN.matcher(identifier);
Expand Down Expand Up @@ -150,8 +140,7 @@ private JsonBrowser getApiResponse(String apiUrl) throws IOException {
request.setHeader("x-tidal-token", TIDAL_TOKEN);
return LavaSrcTools.fetchResponseAsJson(
httpInterfaceManager.getInterface(),
request
);
request);
}

private List<AudioTrack> parseTracks(JsonBrowser json) {
Expand All @@ -169,22 +158,19 @@ private AudioItem getSearchWithRetry(String query, int maxRetries)
throws IOException {
for (int retry = 0; retry <= maxRetries; retry++) {
try {
String apiUrl =
PUBLIC_API_BASE +
"search?query=" +
URLEncoder.encode(query, StandardCharsets.UTF_8) +
"&offset=0&limit=" +
searchLimit +
"&countryCode=" +
countryCode;
String apiUrl = PUBLIC_API_BASE +
"search?query=" +
URLEncoder.encode(query, StandardCharsets.UTF_8) +
"&offset=0&limit=" +
searchLimit +
"&countryCode=" +
countryCode;
var json = getApiResponse(apiUrl);

if (
json.isNull() ||
json.get("tracks").isNull() ||
json.get("tracks").get("items").isNull() ||
json.get("tracks").get("items").text().isEmpty()
) {
if (json.isNull() ||
json.get("tracks").isNull() ||
json.get("tracks").get("items").isNull() ||
json.get("tracks").get("items").text().isEmpty()) {
return AudioReference.NO_TRACK;
}

Expand All @@ -198,8 +184,7 @@ private AudioItem getSearchWithRetry(String query, int maxRetries)
"Tidal Music Search: " + query,
tracks,
null,
true
);
true);
} catch (SocketTimeoutException e) {
if (retry == maxRetries) {
return AudioReference.NO_TRACK;
Expand All @@ -225,8 +210,7 @@ private AudioTrack newMethod(JsonBrowser audio) {
if (rawDuration == null) {
log.warn(
"Skipping track with null duration. Audio JSON: {}",
audio
);
audio);
return null;
}

Expand All @@ -243,14 +227,14 @@ private AudioTrack newMethod(JsonBrowser audio) {
artistName.append(i > 0 ? ", " : "").append(currentArtistName);
}
var coverIdentifier = audio.get("album").get("cover").text();
if (coverIdentifier == null) {
coverIdentifier = "https://tidal.com/_nuxt/img/logos.d8ce10b.jpg";
}
var isrc = audio.get("isrc").text();

var formattedCoverIdentifier = coverIdentifier.replaceAll("-", "/");

var artworkUrl =
"https://resources.tidal.com/images/" +
formattedCoverIdentifier +
"/1280x1280.jpg";
var artworkUrl = "https://resources.tidal.com/images/" +
formattedCoverIdentifier +
"/1280x1280.jpg";
return new TidalAudioTrack(
new AudioTrackInfo(
title,
Expand All @@ -260,36 +244,31 @@ private AudioTrack newMethod(JsonBrowser audio) {
false,
originalUrl,
artworkUrl,
isrc
),
this
);
isrc),
this);
} catch (NumberFormatException e) {
log.error(
"Error parsing duration for track. Audio JSON: {}",
audio,
e
);
e);
return null;
}
}

private AudioItem getAlbumOrPlaylist(
String itemId,
String type,
int maxPageItems
) throws IOException {
int maxPageItems) throws IOException {
try {
// Fetch tracks directly for albums
String apiUrl =
PUBLIC_API_BASE +
type +
"s/" +
itemId +
"/tracks?countryCode=" +
countryCode +
"&limit=" +
maxPageItems;
String apiUrl = PUBLIC_API_BASE +
type +
"s/" +
itemId +
"/tracks?countryCode=" +
countryCode +
"&limit=" +
maxPageItems;
var json = getApiResponse(apiUrl);

if (json == null || json.get("items").isNull()) {
Expand All @@ -302,37 +281,36 @@ private AudioItem getAlbumOrPlaylist(
return AudioReference.NO_TRACK;
}

String itemTitle = "";
String itemInfoUrl = "";

if (type.equalsIgnoreCase("playlist")) {
// Fetch playlist information
itemInfoUrl = PUBLIC_API_BASE + "playlists/" + itemId + "?countryCode=" + countryCode;
} else if (type.equalsIgnoreCase("album")) {
// Fetch album information
itemInfoUrl = PUBLIC_API_BASE + "albums/" + itemId + "?countryCode=" + countryCode;
}

var itemInfoJson = getApiResponse(itemInfoUrl);

if (itemInfoJson != null && !itemInfoJson.get("title").isNull()) {
itemTitle = itemInfoJson.get("title").text();
}

return new BasicAudioPlaylist(itemTitle, items, null, false);
} catch (SocketTimeoutException e) {
log.error("Socket timeout while fetching {} info for ID: {}", type, itemId, e);
} catch (Exception e) {
log.error("Error fetching {} info for ID: {}", type, itemId, e);
}

return AudioReference.NO_TRACK;
String itemTitle = "";
String itemInfoUrl = "";

if (type.equalsIgnoreCase("playlist")) {
// Fetch playlist information
itemInfoUrl = PUBLIC_API_BASE + "playlists/" + itemId + "?countryCode=" + countryCode;
} else if (type.equalsIgnoreCase("album")) {
// Fetch album information
itemInfoUrl = PUBLIC_API_BASE + "albums/" + itemId + "?countryCode=" + countryCode;
}


var itemInfoJson = getApiResponse(itemInfoUrl);

if (itemInfoJson != null && !itemInfoJson.get("title").isNull()) {
itemTitle = itemInfoJson.get("title").text();
}

return new BasicAudioPlaylist(itemTitle, items, null, false);
} catch (SocketTimeoutException e) {
log.error("Socket timeout while fetching {} info for ID: {}", type, itemId, e);
} catch (Exception e) {
log.error("Error fetching {} info for ID: {}", type, itemId, e);
}

return AudioReference.NO_TRACK;
}

public AudioItem getTrack(String trackId) throws IOException {
try {
String apiUrl =
PUBLIC_API_BASE + "tracks/" + trackId + "?countryCode=" + countryCode;
String apiUrl = PUBLIC_API_BASE + "tracks/" + trackId + "?countryCode=" + countryCode;
var json = getApiResponse(apiUrl);

if (json == null || json.isNull()) {
Expand Down Expand Up @@ -378,8 +356,7 @@ public void encodeTrack(AudioTrack track, DataOutput output) {

@Override
public void configureRequests(
Function<RequestConfig, RequestConfig> configurator
) {
Function<RequestConfig, RequestConfig> configurator) {
httpInterfaceManager.configureRequests(configurator);
}

Expand All @@ -400,4 +377,4 @@ public void shutdown() {
public HttpInterface getHttpInterface() {
return httpInterfaceManager.getInterface();
}
}
}

0 comments on commit 3151b3f

Please sign in to comment.