From 887e32bae78634430423d11418c514db0df4d230 Mon Sep 17 00:00:00 2001 From: aka paul <50n50@noreply.localhost> Date: Fri, 23 Jan 2026 20:13:04 +0000 Subject: [PATCH] Update tidal/tidal.js --- tidal/tidal.js | 246 ++++++++++++++++++------------------------------- 1 file changed, 89 insertions(+), 157 deletions(-) diff --git a/tidal/tidal.js b/tidal/tidal.js index e99570e..68cd437 100644 --- a/tidal/tidal.js +++ b/tidal/tidal.js @@ -1,26 +1,31 @@ async function searchResults(keyword) { const results = []; try { - const response = await fetchv2("https://london.monochrome.tf/search/?s=" + encodeURIComponent(keyword)); + const response = await fetchv2("https://triton.squid.wtf/search/?s=" + encodeURIComponent(keyword)); const data = await response.json(); - - if (data.items && Array.isArray(data.items)) { - for (const item of data.items) { + + const items = data.data?.items || data.items || []; + if (Array.isArray(items)) { + for (const item of 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`; } - + + const qualityDisplay = getQualityDisplay(item.audioQuality); + const title = `${item.title || "Unknown Title"} • ${qualityDisplay}`; + const href = `https://hund.qqdl.site/track/?id=${item.id}&quality=${item.audioQuality}`; + results.push({ - title: item.title || "Unknown Title", + title: title, image: imageUrl, - href: item.id ? item.id.toString() : "" + href: href }); } } - + return JSON.stringify(results); } catch (err) { console.error("Search error:", err); @@ -32,112 +37,32 @@ async function searchResults(keyword) { } } -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" - }]); - } +function getQualityDisplay(quality) { + const qualityMap = { + "LOSSLESS": "Hi-Res", + "HIRES_LOSSLESS": "Hi-Res Lossless", + "HIGH": "High", + "LOW": "Low", + "DOLBY_ATMOS": "Dolby Atmos" + }; + return qualityMap[quality] || quality || "Unknown"; } -async function extractEpisodes(id) { +async function extractDetails(url) { + return JSON.stringify([{ + description: "", + aliases: "", + airdate: "" + }]); +} + +async function extractEpisodes(url) { const results = []; try { - results.push({ - href: id, - number: 1 - }); + results.push({ + href: url, + number: 1 + }); return JSON.stringify(results); } catch (err) { return JSON.stringify([{ @@ -147,58 +72,65 @@ async function extractEpisodes(id) { } } -async function extractStreamUrl(ID) { +function decodeBase64(str) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + let result = ''; + let i = 0; + + str = str.replace(/=+$/, ''); + + while (i < str.length) { + const a = chars.indexOf(str.charAt(i++)); + const b = chars.indexOf(str.charAt(i++)); + const c = i < str.length ? chars.indexOf(str.charAt(i++)) : 0; + const d = i < str.length ? chars.indexOf(str.charAt(i++)) : 0; + + const bitmap = (a << 18) | (b << 12) | (c << 6) | d; + + result += String.fromCharCode((bitmap >> 16) & 255); + if (c != 64) result += String.fromCharCode((bitmap >> 8) & 255); + if (d != 64) result += String.fromCharCode(bitmap & 255); + } + + return result; +} + +async function extractStreamUrl(url) { 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) { + const response = await fetchv2(url); + const data = await response.json(); + + if (!data.data) { + console.error("No data field in response"); return "https://error.org/"; } - - const streamObj = json.find(item => item.OriginalTrackUrl); - if (streamObj && streamObj.OriginalTrackUrl) { - return streamObj.OriginalTrackUrl; + + if (!data.data.manifest) { + console.error("No manifest field in response"); + return "https://error.org/"; } - + + try { + const manifestString = data.data.manifest.trim(); + + let decodedManifest = decodeBase64(manifestString); + + decodedManifest = decodedManifest.replace(/\0/g, '').trim(); + + const manifestJson = JSON.parse(decodedManifest); + + if (manifestJson.urls && manifestJson.urls.length > 0) { + return manifestJson.urls[0]; + } else { + console.error("No URLs found in manifest"); + } + } catch (err) { + console.error("Failed to decode/parse manifest:", err.message, err.stack); + } + return "https://error.org/"; - } catch (err) { + console.error("Extract stream URL error:", err.message, err.stack); return "https://error.org/"; } -} +} \ No newline at end of file