UNPKG

musicfree-api

Version:

Multi-platform music API library for downloading and searching across various music services

455 lines (376 loc) 15.8 kB
#!/usr/bin/env node "use strict"; const readline = require('readline'); const path = require('path'); // Import all platform plugins const wy = require('./downloaded_plugins/wy'); const qq = require('./downloaded_plugins/qq'); const kg = require('./downloaded_plugins/kg'); const kw = require('./downloaded_plugins/kw'); const xiaomi = require('./downloaded_plugins/xiaomi'); // Create a map of platforms for easy reference const platforms = { 'wy': { name: '网易云音乐', module: wy }, 'qq': { name: 'QQ音乐', module: qq }, 'kg': { name: '酷狗音乐', module: kg }, 'kw': { name: '酷我音乐', module: kw }, 'xiaomi': { name: '小米音乐', module: xiaomi } }; // Create readline interface const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); // Helper function to prompt user for input function ask(question) { return new Promise(resolve => { rl.question(question, answer => { resolve(answer); }); }); } // Helper function to display search results function displaySearchResults(results) { if (!results.data || results.data.length === 0) { console.log("没有找到相关结果"); return false; } console.log("\n=== 搜索结果 ==="); results.data.forEach((item, index) => { console.log(`${index + 1}. ${item.title} - ${item.artist || ''}`); }); return true; } // Helper function to select from search results async function selectFromResults(results) { if (!displaySearchResults(results)) return null; const choice = await ask("\n请选择序号 (0 返回): "); const index = parseInt(choice) - 1; if (choice === '0') return null; if (isNaN(index) || index < 0 || index >= results.data.length) { console.log("无效的选择"); return null; } return results.data[index]; } // Function to search and download song async function searchAndDownloadSong(platform) { try { const keyword = await ask("\n请输入要搜索的歌曲: "); console.log(`\n正在搜索 "${keyword}"...`); const results = await platform.module.search(keyword, 1, "music"); const song = await selectFromResults(results); if (!song) return; console.log(`\n您选择了: ${song.title} - ${song.artist || ''}`); // Select quality console.log("\n=== 可用音质 ==="); console.log("1. 标准 (128k)"); console.log("2. 高品质 (320k)"); console.log("3. 无损 (如果可用)"); const qualityChoice = await ask("\n请选择音质 [默认:2]: "); let quality; switch(qualityChoice) { case "1": quality = "low"; break; case "3": quality = "super"; break; case "2": default: quality = "high"; } // Get download link console.log(`\n获取 "${song.title}" 的下载链接 (${quality})...`); try { const mediaSource = await platform.module.getMediaSource(song, quality); if (!mediaSource || !mediaSource.url) { console.log("\n无法获取下载链接,可能是VIP歌曲或版权限制"); return; } // Display download info console.log("\n=== 下载信息 ==="); console.log(`歌曲: ${song.title} - ${song.artist || ''}`); console.log(`专辑: ${song.album || "未知"}`); console.log(`音质: ${quality}`); console.log(`URL: ${mediaSource.url}`); // Display download command console.log("\n使用以下curl命令下载:"); const safeFileName = song.title.replace(/[\\/:*?"<>|]/g, '_'); const curlCommand = `curl -L -o "${safeFileName}.mp3" "${mediaSource.url}"`; console.log(curlCommand); // Get lyrics try { console.log("\n获取歌词..."); const lyricResult = await platform.module.getLyric(song); if (lyricResult && lyricResult.rawLrc) { console.log("\n=== 歌词 ==="); console.log(lyricResult.rawLrc); } else { console.log("\n无法获取歌词"); } } catch (e) { console.log("\n获取歌词失败: " + e.message); } } catch (e) { console.log("\n获取下载链接失败: " + e.message); } } catch (error) { console.error("搜索歌曲时出错:", error.message); } } // Function to search and display playlist async function searchAndDisplayPlaylist(platform) { try { const keyword = await ask("\n请输入要搜索的歌单名称: "); console.log(`\n正在搜索歌单 "${keyword}"...`); const results = await platform.module.search(keyword, 1, "sheet"); const playlist = await selectFromResults(results); if (!playlist) return; console.log(`\n您选择了歌单: ${playlist.title} - ${playlist.artist || ''}`); // Get playlist details console.log("\n获取歌单详情..."); try { const sheetInfo = await platform.module.getMusicSheetInfo(playlist, 1); if (sheetInfo.musicList && sheetInfo.musicList.length > 0) { console.log(`\n=== 歌单: ${playlist.title} ===`); if (playlist.description) { console.log(`描述: ${playlist.description}`); } console.log(`\n歌曲列表 (共${sheetInfo.musicList.length}首):\n`); sheetInfo.musicList.forEach((song, index) => { console.log(`${index + 1}. ${song.title} - ${song.artist || ''}`); }); // Ask if user wants to download a song from the playlist const downloadChoice = await ask("\n是否下载歌单中的歌曲? (y/n): "); if (downloadChoice.toLowerCase() === 'y') { const songIndex = parseInt(await ask("\n请选择要下载的歌曲编号: ")) - 1; if (isNaN(songIndex) || songIndex < 0 || songIndex >= sheetInfo.musicList.length) { console.log("无效的选择"); return; } const selectedSong = sheetInfo.musicList[songIndex]; // Select quality console.log("\n=== 可用音质 ==="); console.log("1. 标准 (128k)"); console.log("2. 高品质 (320k)"); console.log("3. 无损 (如果可用)"); const qualityChoice = await ask("\n请选择音质 [默认:2]: "); let quality; switch(qualityChoice) { case "1": quality = "low"; break; case "3": quality = "super"; break; case "2": default: quality = "high"; } // Get download link console.log(`\n获取 "${selectedSong.title}" 的下载链接 (${quality})...`); const mediaSource = await platform.module.getMediaSource(selectedSong, quality); if (!mediaSource || !mediaSource.url) { console.log("\n无法获取下载链接,可能是VIP歌曲或版权限制"); return; } // Display download info console.log("\n=== 下载信息 ==="); console.log(`歌曲: ${selectedSong.title} - ${selectedSong.artist || ''}`); console.log(`专辑: ${selectedSong.album || "未知"}`); console.log(`音质: ${quality}`); console.log(`URL: ${mediaSource.url}`); // Display download command console.log("\n使用以下curl命令下载:"); const safeFileName = selectedSong.title.replace(/[\\/:*?"<>|]/g, '_'); const curlCommand = `curl -L -o "${safeFileName}.mp3" "${mediaSource.url}"`; console.log(curlCommand); // Get lyrics try { console.log("\n获取歌词..."); const lyricResult = await platform.module.getLyric(selectedSong); if (lyricResult && lyricResult.rawLrc) { console.log("\n=== 歌词 ==="); console.log(lyricResult.rawLrc); } else { console.log("\n无法获取歌词"); } } catch (e) { console.log("\n获取歌词失败: " + e.message); } } } else { console.log("\n歌单中没有歌曲或无法获取"); } } catch (e) { console.log("\n获取歌单详情失败: " + e.message); } } catch (error) { console.error("搜索歌单时出错:", error.message); } } // Function to browse top lists async function browseTopLists(platform) { try { console.log("\n获取排行榜列表..."); const topLists = await platform.module.getTopLists(); if (!topLists || (Array.isArray(topLists) && topLists.length === 0)) { console.log("无法获取排行榜信息"); return; } console.log("\n=== 排行榜 ===\n"); // Handle different response formats from different platforms let allLists = []; if (Array.isArray(topLists)) { // Simple array format topLists.forEach((list, index) => { console.log(`${index + 1}. ${list.title || list.name}`); allLists.push(list); }); } else if (topLists.data) { // Format with categories let listIndex = 1; topLists.data.forEach(category => { console.log(`[${category.title}]`); category.data.forEach(list => { console.log(`${listIndex}. ${list.title || list.name}`); allLists.push(list); listIndex++; }); console.log(""); }); } const rankIndex = parseInt(await ask("\n请选择要查看的排行榜序号 (0 返回): ")) - 1; if (rankIndex < 0 || isNaN(rankIndex) || rankIndex >= allLists.length) { console.log("无效的选择"); return; } const selectedRank = allLists[rankIndex]; console.log(`\n获取排行榜详情: ${selectedRank.title || selectedRank.name}...`); try { const rankDetail = await platform.module.getTopListDetail(selectedRank); if (rankDetail.musicList && rankDetail.musicList.length > 0) { console.log(`\n=== ${rankDetail.title || rankDetail.name} ===`); if (rankDetail.description) { console.log(`${rankDetail.description}\n`); } rankDetail.musicList.forEach((song, index) => { console.log(`${index + 1}. ${song.title} - ${song.artist || ''}`); }); const downloadChoice = await ask("\n是否下载排行榜中的歌曲? (y/n): "); if (downloadChoice.toLowerCase() === 'y') { const songIndex = parseInt(await ask("\n请选择要下载的歌曲编号: ")) - 1; if (isNaN(songIndex) || songIndex < 0 || songIndex >= rankDetail.musicList.length) { console.log("无效的选择"); return; } const selectedSong = rankDetail.musicList[songIndex]; // Select quality console.log("\n=== 可用音质 ==="); console.log("1. 标准 (128k)"); console.log("2. 高品质 (320k)"); console.log("3. 无损 (如果可用)"); const qualityChoice = await ask("\n请选择音质 [默认:2]: "); let quality; switch(qualityChoice) { case "1": quality = "low"; break; case "3": quality = "super"; break; case "2": default: quality = "high"; } // Get download link console.log(`\n获取 "${selectedSong.title}" 的下载链接 (${quality})...`); const mediaSource = await platform.module.getMediaSource(selectedSong, quality); if (!mediaSource || !mediaSource.url) { console.log("\n无法获取下载链接,可能是VIP歌曲或版权限制"); return; } // Display download info console.log("\n=== 下载信息 ==="); console.log(`歌曲: ${selectedSong.title} - ${selectedSong.artist || ''}`); console.log(`专辑: ${selectedSong.album || "未知"}`); console.log(`音质: ${quality}`); console.log(`URL: ${mediaSource.url}`); // Display download command console.log("\n使用以下curl命令下载:"); const safeFileName = selectedSong.title.replace(/[\\/:*?"<>|]/g, '_'); const curlCommand = `curl -L -o "${safeFileName}.mp3" "${mediaSource.url}"`; console.log(curlCommand); // Get lyrics try { console.log("\n获取歌词..."); const lyricResult = await platform.module.getLyric(selectedSong); if (lyricResult && lyricResult.rawLrc) { console.log("\n=== 歌词 ==="); console.log(lyricResult.rawLrc); } else { console.log("\n无法获取歌词"); } } catch (e) { console.log("\n获取歌词失败: " + e.message); } } } else { console.log("\n排行榜中没有歌曲或无法获取"); } } catch (e) { console.log("\n获取排行榜详情失败: " + e.message); } } catch (error) { console.error("获取排行榜时出错:", error.message); } } // Main function to show menu and handle user choices async function main() { // Display header console.log("===================================="); console.log(" 音乐下载工具 - 多平台整合版"); console.log("====================================\n"); // Platform selection console.log("可用平台:"); Object.entries(platforms).forEach(([key, value], index) => { console.log(`${index + 1}. ${value.name} (${key})`); }); const platformChoice = await ask("\n请选择平台 [1-5]: "); const platformIndex = parseInt(platformChoice) - 1; if (isNaN(platformIndex) || platformIndex < 0 || platformIndex >= Object.keys(platforms).length) { console.log("无效的选择"); rl.close(); return; } const selectedPlatformKey = Object.keys(platforms)[platformIndex]; const selectedPlatform = platforms[selectedPlatformKey]; console.log(`\n已选择: ${selectedPlatform.name}`); // Main menu loop let running = true; while (running) { console.log("\n=== 主菜单 ==="); console.log("1. 搜索并下载歌曲"); console.log("2. 搜索并浏览歌单"); console.log("3. 浏览排行榜"); console.log("4. 切换平台"); console.log("5. 退出"); const choice = await ask("\n请选择操作 [1-5]: "); switch(choice) { case "1": await searchAndDownloadSong(selectedPlatform); break; case "2": await searchAndDisplayPlaylist(selectedPlatform); break; case "3": await browseTopLists(selectedPlatform); break; case "4": // Return to platform selection by restarting rl.close(); process.nextTick(() => { require(process.argv[1]); }); return; case "5": console.log("\n感谢使用,再见!"); running = false; break; default: console.log("无效的选择,请重试"); } } rl.close(); } // Start the application main().catch(error => { console.error("程序出错:", error); rl.close(); });