-
Notifications
You must be signed in to change notification settings - Fork 0
/
code.js
130 lines (109 loc) · 4.36 KB
/
code.js
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
require('dotenv').config();
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const { exec } = require('child_process');
const search = require('yt-search');
const ytdl = require('ytdl-core');
const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const readline = require('readline');
const clientId = process.env.SPOTIFY_CLIENT_ID;
const clientSecret = process.env.SPOTIFY_CLIENT_SECRET;
const playlistFolder = './playlist/';
async function getAccessToken() {
try {
// Get access token using cURL
const curlCommand = `curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=${clientId}" -d "client_secret=${clientSecret}" -d "grant_type=client_credentials" https://accounts.spotify.com/api/token`;
const { stdout, stderr } = await new Promise((resolve) => {
exec(curlCommand, (error, stdout, stderr) => {
resolve({ stdout, stderr });
});
});
const accessToken = JSON.parse(stdout).access_token;
return accessToken;
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
async function createPlaylistFolder() {
if (!fs.existsSync(playlistFolder)) {
fs.mkdirSync(playlistFolder);
console.log(`Created playlist folder: ${playlistFolder}`);
}
}
async function downloadAndConvertToMP3(videoId, outputPath, fileName) {
return new Promise((resolve, reject) => {
const videoUrl = `https://www.youtube.com/watch?v=${videoId}`;
console.log(`Downloading audio from videoId: ${videoId}`);
const stream = ytdl(videoUrl, {filter: 'audioonly'})
const filePath = path.join(outputPath, `${fileName}.mp3`);
ffmpeg.setFfmpegPath(ffmpegPath);
const ffmpegProcess = ffmpeg()
.input(stream)
.audioCodec('libmp3lame')
.toFormat('mp3')
.on('end', () => {
// Check if the file exists and has a non-zero size
const stats = fs.statSync(filePath);
if (stats.isFile() && stats.size > 0) {
console.log(`Downloaded and converted ${fileName}.mp3`);
resolve(filePath);
} else {
console.error(`Error: ${fileName}.mp3 is empty or does not exist`);
reject(new Error(`File ${fileName}.mp3 is empty or does not exist`));
}
})
.on('error', (err) => {
console.error(`Error downloading and converting: ${err.message}`);
reject(err);
})
.save(filePath);
});
}
async function getPlaylistInfo(accessToken, playlistId) {
try {
await createPlaylistFolder();
// Get playlist details
const playlistResponse = await axios.get(`https://api.spotify.com/v1/playlists/${playlistId}`, {
headers: {
'Authorization': `Bearer ${accessToken}`,
},
});
const playlist = playlistResponse.data;
console.log('Playlist Information:');
console.log(`Name: ${playlist.name}`);
console.log(`Description: ${playlist.description}`);
console.log('Tracks:');
// Iterate through the tracks
playlist.tracks.items.forEach(async (item, index) => {
const track = item.track;
console.log(`${index + 1}. ${track.name} - ${track.artists.map(artist => artist.name).join(', ')}`);
// Search for the track on YouTube
const searchQuery = `${track.name} - ${track.artists[0].name}`;
const searchResults = await search(searchQuery);
const videoId = searchResults.all[0].videoId;
await downloadAndConvertToMP3(videoId, path.join(__dirname, playlistFolder), `${track.name} - ${track.artists[0].name}`);
});
} catch (error) {
console.error('Error:', error.message);
}
}
async function main() {
try {
const accessToken = await getAccessToken();
// Get playlist ID from the user
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the Spotify Playlist ID: ', async (playlistId) => {
rl.close();
await getPlaylistInfo(accessToken, playlistId);
});
} catch (error) {
console.error('Error:', error.message);
}
}
main();