Skip to content

Commit

Permalink
added support for mixes, cleaned up code kinda
Browse files Browse the repository at this point in the history
  • Loading branch information
nansess authored and nansess committed Aug 14, 2024
1 parent ca22a8e commit 9ae621f
Showing 1 changed file with 49 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package com.github.topi314.lavasrc.tidal;

import com.github.topi314.lavasearch.AudioSearchManager;
import com.github.topi314.lavasrc.ExtendedAudioPlaylist;
import com.github.topi314.lavasrc.LavaSrcTools;
import com.github.topi314.lavasrc.mirror.DefaultMirroringAudioTrackResolver;
import com.github.topi314.lavasrc.mirror.MirroringAudioSourceManager;
import com.github.topi314.lavasrc.mirror.MirroringAudioTrackResolver;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManager;
import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser;
import com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools;
import com.sedmelluq.discord.lavaplayer.tools.io.HttpConfigurable;
Expand Down Expand Up @@ -36,15 +33,14 @@
public class TidalSourceManager extends MirroringAudioSourceManager 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|mix)/(?<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 TIDAL_TOKEN = "i4ZDjcyhed7Mu47q";

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

private final HttpInterfaceManager httpInterfaceManager = HttpClientTools.createDefaultThreadLocalManager();
Expand Down Expand Up @@ -87,6 +83,8 @@ public AudioItem loadItem(AudioPlayerManager manager, AudioReference reference)
switch (type) {
case "album":
return getAlbumOrPlaylist(id, "album", ALBUM_MAX_PAGE_ITEMS);
case "mix":
return getMix(id);
case "track":
return getTrack(id);
case "playlist":
Expand Down Expand Up @@ -126,48 +124,34 @@ private List<AudioTrack> parseTracks(JsonBrowser json) {
return tracks;
}

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;
var json = getApiResponse(apiUrl);

if (json.get("tracks").get("items").isNull()) {
return AudioReference.NO_TRACK; // devo bullied me :(
}
private AudioItem getSearch(String query) throws IOException {
try {
String apiUrl = PUBLIC_API_BASE +
"search?query=" +
URLEncoder.encode(query, StandardCharsets.UTF_8) +
"&offset=0&limit=" +
searchLimit +
"&countryCode=" +
countryCode;
var json = getApiResponse(apiUrl);

var tracks = parseTracks(json.get("tracks").get("items"));
if (json.get("tracks").get("items").isNull()) {
return AudioReference.NO_TRACK;
}

if (tracks.isEmpty()) {
return AudioReference.NO_TRACK;
}
var tracks = parseTracks(json.get("tracks").get("items"));

return new BasicAudioPlaylist("Tidal Music Search: " + query, tracks, null, true);
} catch (SocketTimeoutException e) {
if (retry == maxRetries) {
return AudioReference.NO_TRACK;
}
if (tracks.isEmpty()) {
return AudioReference.NO_TRACK;
}
}
return AudioReference.NO_TRACK;
}

private AudioItem getSearch(String query) throws IOException {
int maxRetries = 2;
return getSearchWithRetry(query, maxRetries);
return new BasicAudioPlaylist("Tidal Music Search: " + query, tracks, null, true);
} catch (SocketTimeoutException e) {
return AudioReference.NO_TRACK;
}
}

private AudioTrack parseTrack(JsonBrowser audio) {
return newMethod(audio);
}

private AudioTrack newMethod(JsonBrowser audio) {
var id = audio.get("id").text();
var rawDuration = audio.get("duration").text();

Expand All @@ -178,7 +162,6 @@ private AudioTrack newMethod(JsonBrowser audio) {

try {
var duration = Long.parseLong(rawDuration) * 1000;

var title = audio.get("title").text();
var originalUrl = audio.get("url").text();
var artistsArray = audio.get("artists");
Expand Down Expand Up @@ -208,7 +191,6 @@ private AudioTrack newMethod(JsonBrowser audio) {

private AudioItem getAlbumOrPlaylist(String itemId, String type, int maxPageItems) throws IOException {
try {
// Fetch tracks directly for albums
String apiUrl = PUBLIC_API_BASE +
type +
"s/" +
Expand All @@ -233,10 +215,8 @@ private AudioItem getAlbumOrPlaylist(String itemId, String type, int maxPageItem
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;
}

Expand Down Expand Up @@ -281,23 +261,44 @@ public AudioItem getTrack(String trackId) throws IOException {
}
}

public AudioItem getMix(String mixId) throws IOException {
try {
String apiUrl = PUBLIC_API_BASE + "mixes/" + mixId + "/items?countryCode=" + countryCode;
var json = getApiResponse(apiUrl);

if (json == null || json.get("items").isNull()) {
log.info("Mix not found for ID: {}", mixId);
return AudioReference.NO_TRACK;
}

var items = parseTrackItem(json);

if (items.isEmpty()) {
return AudioReference.NO_TRACK;
}

log.info("Mix loaded successfully for ID: {}", mixId);
return new BasicAudioPlaylist("Mix: " + mixId, items, null, false);
} catch (SocketTimeoutException e) {
log.error("Socket timeout while fetching track with ID: {}", mixId, e);
return AudioReference.NO_TRACK;
}
}

private List<AudioTrack> parseTrackItem(JsonBrowser json) {
var tracks = new ArrayList<AudioTrack>();
var items = json.get("items");

for (var audio : items.values()) {
var parsedTrack = parseItem(audio);
JsonBrowser item = audio.get("item").isNull() ? audio : audio.get("item");
var parsedTrack = parseTrack(item);
if (parsedTrack != null) {
tracks.add(parsedTrack);
}
}
return tracks;
}

private AudioTrack parseItem(JsonBrowser audio) {
return newMethod(audio);
}

@Override
public void encodeTrack(AudioTrack track, DataOutput output) {
}
Expand Down

0 comments on commit 9ae621f

Please sign in to comment.