Back to Home
Gistify Snippet
kyiov
Sep 4·1 file(s)
Public

Scraper lirik - open.spotify.com

Scraper lirik - open.spotify.com

#github-gist#javascript#gist:fb504e3b047e70242dff1aac81eee395#gistsync:2026-09-02T10:46:00Z
1
Raw
lyrics.jsjavascript
104 lines
1import axios from 'axios';
2
3const QUERY = "Bohemian Rhapsody";
4const ARTIST = "Queen";
5
6export 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
84export const lyricsV2 = getLyrics;
85
86const __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
93if (__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.