Spaces:
Paused
Paused
File size: 5,562 Bytes
d145b59 7ffa092 d145b59 7ffa092 d145b59 de913e8 d145b59 16bd39e 3ed6900 16bd39e d145b59 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
const axios = require('axios');
const yts = require("yt-search");
const { getAudio } = require("../lib/ytdl");
const path = require("path");
const fs = require("fs");
const dirTmp = path.join(__dirname, "../tmp");
const clientId = '8f777f61f80e4051b754d8e50310ad6e';
const clientSecret = '5802d3726d3149bfb880a577aa855fb3';
const tokenUrl = 'https://accounts.spotify.com/api/token';
const base64Credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
// Pastikan folder tmp ada
if (!fs.existsSync(dirTmp)) {
fs.mkdirSync(dirTmp, { recursive: true });
}
async function getAccessToken() {
try {
const response = await axios.post(tokenUrl, 'grant_type=client_credentials', {
headers: {
'Authorization': `Basic ${base64Credentials}`,
'Content-Type': 'application/x-www-form-urlencoded',
},
});
return response.data.access_token;
} catch (error) {
console.error('Gagal mendapatkan token:', error.response?.data || error.message);
return null;
}
}
async function spotifyTrack(trackUrl) {
const { ID3Writer } = await import('browser-id3-writer');
try {
const match = trackUrl.match(/track\/([a-zA-Z0-9]+)/);
if (!match) throw new Error('URL tidak valid');
const trackId = match[1];
// Dapatkan token
const accessToken = await getAccessToken();
if (!accessToken) throw new Error('Gagal mendapatkan token akses');
// Ambil metadata Spotify
const trackResponse = await axios.get(`https://api.spotify.com/v1/tracks/${trackId}`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
const trackData = trackResponse.data;
// Cari lagu di YouTube
const searchResults = await yts(`${trackData.name} - ${trackData.artists.map(a => a.name).join(', ')}`);
if (!searchResults.videos.length) throw new Error('Video tidak ditemukan di YouTube');
const videoUrl = searchResults.videos[0].url;
const audio = await getAudio(videoUrl);
if (!audio) throw new Error("Gagal mendapatkan audio dari YouTube");
// Simpan file dengan nama unik
const Filename = `NSpotify_${Date.now()}_${Math.floor(Math.random() * 1000)}.mp3`;
const FilenameM = `Spotify_${Date.now()}_${Math.floor(Math.random() * 1000)}.mp3`;
await fs.writeFileSync(`${dirTmp}/${Filename}`, audio);
// Tambahkan ID3 Tag
const writer = new ID3Writer(fs.readFileSync(`${dirTmp}/${Filename}`));
writer
.setFrame('TIT2', trackData.name)
.setFrame('TPE1', trackData.artists.map(a => a.name))
.setFrame('TALB', trackData.album.name || "")
.setFrame('TYER', parseInt(trackData.album.release_date.split('-')[0]))
.setFrame('APIC', {
type: 3,
data: await urlToBuffer(trackData.album.images[0]?.url),
description: 'Super picture'
})
.addTag();
// Simpan file dengan tag ID3
const taggedSongBuffer = Buffer.from(writer.arrayBuffer);
await fs.writeFileSync(`${dirTmp}/${FilenameM}`, taggedSongBuffer);
const URI = `https://fullpwerr-hutatools.hf.space/tmp/${FilenameM}`;
const res = {
status: 200,
title: trackData.name,
artist: trackData.artists.map(artist => artist.name).join(', '),
album: trackData.album.name,
duration_ms: trackData.duration_ms,
release_date: trackData.album.release_date,
thumbnail: trackData.album.images[0]?.url || null,
music: [{ url: URI }]
};
console.log(res)
return res
} catch (e) {
return { status: 500, message: e.message}
}
}
async function spotifyPlaylist(playlistUrl) {
try {
const match = playlistUrl.match(/playlist\/([a-zA-Z0-9]+)/);
if (!match) throw new Error('URL playlist tidak valid');
const playlistId = match[1];
const accessToken = await getAccessToken();
if (!accessToken) throw new Error('Gagal mendapatkan token akses');
const playlistResponse = await axios.get(`https://api.spotify.com/v1/playlists/${playlistId}`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
const playlistData = playlistResponse.data;
const tracks = playlistData.tracks.items;
if (!tracks.length) throw new Error('Playlist kosong atau tidak ditemukan');
console.log(`🎵 Playlist: ${playlistData.name} (${tracks.length} lagu)`);
let results = [];
const limitedTracks = tracks.slice(0, 3);
for (const item of limitedTracks) {
const track = item.track;
if (!track) continue;
const trackUrl = `https://open.spotify.com/track/${track.id}`;
console.log(`🔄 Memproses: ${track.name} - ${track.artists.map(a => a.name).join(', ')}`);
const trackData = await spotifyTrack(trackUrl);
if (trackData) results.push(trackData.music[0].url);
}
return {
status: 200,
playlist_name: playlistData.name,
total_tracks: tracks.length,
cover_image: playlistData.images[0]?.url || null,
tracks: results
};
} catch (error) {
console.error(error);
return null;
}
}
const urlToBuffer = async (url, options) => {
try {
options ? options : {};
const res = await axios({
method: "get",
url,
headers: {
'DNT': 1,
'Upgrade-Insecure-Request': 1
},
...options,
responseType: 'arraybuffer'
});
return res.data;
} catch (e) {
console.log(`Error : ${e}`);
}
};
module.exports = {
spotifyTrack,
spotifyPlaylist
} |