Add tidal/tidal.js

This commit is contained in:
aka paul 2025-11-20 22:54:42 +00:00
parent 866a5b7506
commit 8b55dce812

204
tidal/tidal.js Normal file
View file

@ -0,0 +1,204 @@
async function searchResults(keyword) {
const results = [];
try {
const response = await fetchv2("https://london.monochrome.tf/search/?s=" + encodeURIComponent(keyword));
const data = await response.json();
if (data.items && Array.isArray(data.items)) {
for (const item of data.items) {
let imageUrl = "";
if (item.album && item.album.cover) {
const cover = item.album.cover.replace(/-/g, '/');
imageUrl = `https://resources.tidal.com/images/${cover}/1280x1280.jpg`;
}
results.push({
title: item.title || "Unknown Title",
image: imageUrl,
href: item.id ? item.id.toString() : ""
});
}
}
return JSON.stringify(results);
} catch (err) {
console.error("Search error:", err);
return JSON.stringify([{
title: "Error",
image: "Error",
href: "Error"
}]);
}
}
async function extractDetails(ID) {
const endpoints = [
"https://tidal.kinoplus.online/track/",
"https://katze.qqdl.site/track/",
"https://wolf.qqdl.site/track/",
"https://london.monochrome.tf/track/"
];
const startTime = Date.now();
let json = null;
async function tryEndpoints() {
const promises = endpoints.map(async endpoint => {
try {
const response = await fetchv2(`${endpoint}?id=${encodeURIComponent(ID)}&quality=LOSSLESS`);
const data = await response.json();
if (data.detail === "Too Many Requests") return null;
if (Array.isArray(data) && data.length > 0) return data;
return null;
} catch {
return null;
}
});
const results = await Promise.allSettled(promises);
for (const result of results) {
if (result.status === 'fulfilled' && result.value !== null) {
return result.value;
}
}
return null;
}
while (Date.now() - startTime < 10000) {
json = await tryEndpoints();
if (json) break;
await new Promise(resolve => setTimeout(resolve, 100));
}
if (!json) {
return JSON.stringify([{
description: "Error loading track details",
aliases: "Error",
airdate: "Error"
}]);
}
try {
let trackInfo = json.find(item => item.duration && item.title);
if (!trackInfo) throw new Error("Track info not found");
const artists = trackInfo.artists ? trackInfo.artists.map(a => a.name).join(", ") : "Unknown Artist";
const album = trackInfo.album ? trackInfo.album.title : "Unknown Album";
const duration = trackInfo.duration ? Math.floor(trackInfo.duration / 60) + ":" + String(trackInfo.duration % 60).padStart(2, '0') : "Unknown";
const audioQuality = trackInfo.audioQuality || "Unknown";
const audioModes = trackInfo.audioModes ? trackInfo.audioModes.join(", ") : "STEREO";
const copyright = trackInfo.copyright || "";
const bpm = trackInfo.bpm ? `${trackInfo.bpm} BPM` : "";
const key = trackInfo.key && trackInfo.keyScale ? `${trackInfo.key} ${trackInfo.keyScale}` : "";
const explicit = trackInfo.explicit ? "🅴 Explicit" : "";
let description = `🎵 ${trackInfo.title}\n`;
description += `👤 Artist: ${artists}\n`;
description += `💿 Album: ${album}\n`;
description += `⏱️ Duration: ${duration}\n`;
description += `🎧 Quality: ${audioQuality} (${audioModes})\n`;
if (trackInfo.popularity) description += `📊 Popularity: ${trackInfo.popularity}%\n`;
if (bpm) {
description += `🎼 ${bpm}`;
if (key) description += ` | Key: ${key}`;
description += `\n`;
}
if (explicit) description += `${explicit}\n`;
if (copyright) description += `\n© ${copyright}`;
const airdate = trackInfo.streamStartDate
? new Date(trackInfo.streamStartDate).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
: "N/A";
const featuredArtists = trackInfo.artists
? trackInfo.artists.filter(a => a.type === "FEATURED").map(a => a.name).join(", ")
: "N/A";
return JSON.stringify([{
description: description.trim(),
aliases: featuredArtists || "N/A",
airdate: airdate
}]);
} catch (err) {
console.error("Extract details error:", err);
return JSON.stringify([{
description: "Error loading track details",
aliases: "Error",
airdate: "Error"
}]);
}
}
async function extractEpisodes(id) {
const results = [];
try {
results.push({
href: id,
number: 1
});
return JSON.stringify(results);
} catch (err) {
return JSON.stringify([{
href: "Error",
number: "Error"
}]);
}
}
async function extractStreamUrl(ID) {
try {
const endpoints = [
"https://tidal.kinoplus.online/track/",
"https://katze.qqdl.site/track/",
"https://wolf.qqdl.site/track/",
"https://london.monochrome.tf/track/"
];
const startTime = Date.now();
let json = null;
async function tryEndpoints() {
const promises = endpoints.map(async endpoint => {
try {
const response = await fetchv2(`${endpoint}?id=${encodeURIComponent(ID)}&quality=LOSSLESS`);
const data = await response.json();
if (data.detail === "Too Many Requests") return null;
if (Array.isArray(data) && data.length > 0) return data;
return null;
} catch {
return null;
}
});
const results = await Promise.allSettled(promises);
for (const result of results) {
if (result.status === 'fulfilled' && result.value !== null) {
return result.value;
}
}
return null;
}
while (Date.now() - startTime < 10000) {
json = await tryEndpoints();
if (json) break;
await new Promise(resolve => setTimeout(resolve, 100));
}
if (!json) {
return "https://error.org/";
}
const streamObj = json.find(item => item.OriginalTrackUrl);
if (streamObj && streamObj.OriginalTrackUrl) {
return streamObj.OriginalTrackUrl;
}
return "https://error.org/";
} catch (err) {
return "https://error.org/";
}
}