Back to Home
Gistify Snippet
Public
Scraper lirik - open.spotify.com
Scraper lirik - open.spotify.com
#github-gist#javascript#gist:fb504e3b047e70242dff1aac81eee395#gistsync:2026-09-02T10:46:00Z
1
Rawlyrics.jsjavascript
104 lines| 1 | import axios from 'axios'; |
| 2 | |
| 3 | const QUERY = "Bohemian Rhapsody"; |
| 4 | const ARTIST = "Queen"; |
| 5 | |
| 6 | export async function getLyrics(queryOrTrack, artist = "") { |
| 7 | if (!queryOrTrack || !queryOrTrack.trim()) { |
| 8 | throw new Error("Parameter 'q' (judul lagu atau link Spotify) wajib diisi."); |
| 9 | } |
| 10 | |
| 11 | let trackName = String(queryOrTrack).trim(); |
| 12 | let artistName = String(artist || "").trim(); |
| 13 | |
| 14 | if (trackName.includes("spotify.com/track/")) { |
| 15 | const match = trackName.match(/track\/([a-zA-Z0-9]+)/); |
| 16 | if (match) { |
| 17 | try { |
| 18 | const oembed = await axios.get( |
| 19 | `https://open.spotify.com/oembed?url=https://open.spotify.com/track/${match[1]}`, |
| 20 | { timeout: 5000 } |
| 21 | ); |
| 22 | trackName = oembed.data?.title?.replace(/\(feat\..*?\)/i, "").trim() || trackName; |
| 23 | const resEmbed = await axios.get(`https://open.spotify.com/embed/track/${match[1]}`); |
| 24 | const matchArtist = resEmbed.data.match(/"artists":\[\{"name":"([^"]+)"/); |
| 25 | if (matchArtist && !artistName) artistName = matchArtist[1]; |
| 26 | } catch (_) {} |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | try { |
| 31 | const res = await axios.get("https: |
| 32 | params: { track_name: trackName, artist_name: artistName }, |
| 33 | headers: { |
| 34 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" |
| 35 | }, |
| 36 | timeout: 10000, |
| 37 | }); |
| 38 | if (res.data && (res.data.plainLyrics || res.data.syncedLyrics)) { |
| 39 | const dur = res.data.duration; |
| 40 | return { |
| 41 | status: true, |
| 42 | trackName: res.data.trackName || trackName, |
| 43 | artistName: res.data.artistName || artistName || "Unknown Artist", |
| 44 | albumName: res.data.albumName || null, |
| 45 | duration: dur || null, |
| 46 | durationFormatted: dur ? `${Math.floor(dur / 60)}:${String(Math.floor(dur % 60)).padStart(2, "0")}` : null, |
| 47 | hasSynced: Boolean(res.data.syncedLyrics), |
| 48 | plainLyrics: res.data.plainLyrics || null, |
| 49 | syncedLyrics: res.data.syncedLyrics || null, |
| 50 | }; |
| 51 | } |
| 52 | } catch (_) {} |
| 53 | |
| 54 | try { |
| 55 | const searchRes = await axios.get("https://lrclib.net/api/search", { |
| 56 | params: { q: `${trackName} ${artistName}`.trim() }, |
| 57 | headers: { |
| 58 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" |
| 59 | }, |
| 60 | timeout: 10000, |
| 61 | }); |
| 62 | if (Array.isArray(searchRes.data) && searchRes.data.length > 0) { |
| 63 | const best = searchRes.data[0]; |
| 64 | const dur = best.duration; |
| 65 | return { |
| 66 | status: true, |
| 67 | trackName: best.trackName, |
| 68 | artistName: best.artistName || "Unknown Artist", |
| 69 | albumName: best.albumName || null, |
| 70 | duration: dur || null, |
| 71 | durationFormatted: dur ? `${Math.floor(dur / 60)}:${String(Math.floor(dur % 60)).padStart(2, "0")}` : null, |
| 72 | hasSynced: Boolean(best.syncedLyrics), |
| 73 | plainLyrics: best.plainLyrics || null, |
| 74 | syncedLyrics: best.syncedLyrics || null, |
| 75 | }; |
| 76 | } |
| 77 | } catch (err) { |
| 78 | throw new Error(err.message || "Gagal mengambil lirik lagu."); |
| 79 | } |
| 80 | |
| 81 | throw new Error("Lirik lagu tidak ditemukan."); |
| 82 | } |
| 83 | |
| 84 | export const lyricsV2 = getLyrics; |
| 85 | |
| 86 | const __is_main = (() => { |
| 87 | try { |
| 88 | if (!process.argv[1]) return false; |
| 89 | return import.meta.url.endsWith(process.argv[1].replace(/\\/g, '/')); |
| 90 | } catch (_) { return false; } |
| 91 | })(); |
| 92 | |
| 93 | if (__is_main) { |
| 94 | (async () => { |
| 95 | try { |
| 96 | const result = await getLyrics(QUERY, ARTIST); |
| 97 | console.log(JSON.stringify(result, null, 2)); |
| 98 | } catch (e) { |
| 99 | console.error('Error: ' + (e && e.message ? e.message : e)); |
| 100 | process.exitCode = 1; |
| 101 | } |
| 102 | })(); |
| 103 | } |
| 104 | |
Discussion & Comments0
No comments yet — be the first to leave feedback or start a code discussion.
Sign in with your GitHub account to write comments and join the discussion.