### Start Proxy Server (CLI) Source: https://context7.com/unblockneteasemusic/server/llms.txt Start the HTTP/HTTPS proxy server from the command line to intercept and modify requests from the Netease Cloud Music client. ```APIDOC ## Start Proxy Server (CLI) ### Description Start the HTTP/HTTPS proxy server from the command line to intercept and modify requests from the Netease Cloud Music client. ### Usage ```bash # Install npm install -g @unblockneteasemusic/server # Or run directly with npx npx -p @unblockneteasemusic/server unblockneteasemusic # Basic startup (default HTTP:8080 / HTTPS:8081) unblockneteasemusic # Specify ports (HTTP:80, HTTPS:443) unblockneteasemusic -p 80:443 # Specify listen address and ports unblockneteasemusic -p 8080:8081 -a 0.0.0.0 # Specify source priority (only use qq and kuwo) unblockneteasemusic -o qq kuwo # Enable strict mode (only proxy Netease Cloud Music domains to prevent abuse) unblockneteasemusic -s # Use upstream proxy (for YouTube source) unblockneteasemusic -u http://127.0.0.1:7890 # Force specify Netease Cloud Music server IP (to avoid request loops due to hosts modification) unblockneteasemusic -f 59.111.181.60 # Set proxy authentication password unblockneteasemusic -t user:password # Replace virtual endpoints with public addresses (required for PC/UWP clients) unblockneteasemusic -e https://music.163.com # Enable mainland relay (get music URLs via a relay server) unblockneteasemusic -c relay.example.com:8080 # Docker startup, specify sources and enable lossless quality docker run -e ENABLE_FLAC=true pan93412/unblock-netease-music-enhanced -o kugou migu ytdlp ``` ``` -------------------------------- ### Install UnblockNeteaseMusic Server via NPM Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Install the server as a project dependency using npm or yarn. ```bash npm install @unblockneteasemusic/server yarn add @unblockneteasemusic/server # for Yarn users ``` -------------------------------- ### Start the proxy server using CLI Source: https://context7.com/unblockneteasemusic/server/llms.txt Launch the HTTP/HTTPS proxy server from the command line to intercept and modify Netease Cloud Music requests. Various options are available for port configuration, source prioritization, strict mode, upstream proxies, and authentication. ```bash # 安装 npm install -g @unblockneteasemusic/server # 或通过 npx 直接运行 npx -p @unblockneteasemusic/server unblockneteasemusic # 基本启动(默认 HTTP:8080 / HTTPS:8081) unblockneteasemusic # 指定端口(HTTP:80,HTTPS:443) unblockneteasemusic -p 80:443 # 指定监听地址和端口 unblockneteasemusic -p 8080:8081 -a 0.0.0.0 # 指定音源优先级(只使用 qq 和 kuwo) unblockneteasemusic -o qq kuwo # 启用严格模式(仅代理网易云域名,防止被滥用) unblockneteasemusic -s # 使用上游代理(翻墙代理,用于 YouTube 音源) unblockneteasemusic -u http://127.0.0.1:7890 # 强制指定网易云服务器 IP(避免 hosts 修改导致请求死循环) unblockneteasemusic -f 59.111.181.60 # 设置代理认证密码 unblockneteasemusic -t user:password # 替换虚拟端点为公网地址(PC/UWP 客户端需要) unblockneteasemusic -e https://music.163.com # 开启大陆中转(通过中继服务器获取音乐 URL) unblockneteasemusic -c relay.example.com:8080 # Docker 启动,指定音源并开启无损音质 docker run -e ENABLE_FLAC=true pan93412/unblock-netease-music-enhanced -o kugou migu ytdlp ``` -------------------------------- ### Run UnblockNeteaseMusic Server with NPX Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Execute the UnblockNeteaseMusic server directly using npx without global installation. ```bash npx -p @unblockneteasemusic/server unblockneteasemusic ``` -------------------------------- ### Register UnblockNeteaseMusic as a Windows Service Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Install the server as a Windows service by running the nw.js script. Configuration for HTTP proxy and environment variables can be done in nw.js. Uninstall by running the script again. Logs are stored in the 'daemon' folder. ```bash node ./nw.js ``` -------------------------------- ### Compile and Run Latest Development Version Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Install dependencies, build the project, and run the latest development version using Node.js. This is for testing the most recent code changes. ```bash yarn yarn build node app.js # 即可使用 repo 的最新开发内容 ``` -------------------------------- ### Use Latest Development Version Without Compiling Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Install dependencies and run the latest development version directly using Node.js with the DEVELOPMENT=true flag. This allows testing without a full build process. ```bash yarn DEVELOPMENT=true yarn node app.js ``` -------------------------------- ### Start Bridge Server and Make HTTP Requests Source: https://context7.com/unblockneteasemusic/server/llms.txt Run the bridge server as an independent HTTP server to provide music source search capabilities. Use HTTP requests to call various music source Providers via URL paths. Ensure the song info is properly JSON encoded and URL encoded. ```javascript // 启动 bridge 服务器(默认端口 9000) // node src/bridge.js [port] // node src/bridge.js 9000 // 通过 HTTP 请求调用音源 // 格式:GET http://localhost:9000/{provider}/{method}?{songInfo_JSON} const songInfoJson = encodeURIComponent(JSON.stringify({ id: 418602084, name: '告白气球', duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], keyword: '告白气球 - 周杰伦', })); // 调用酷狗 search 接口 fetch(`http://localhost:9000/kugou/search?${songInfoJson}`) .then((res) => res.text()) .then((url) => console.log('酷狗搜索结果:', url)); // 调用咪咕 check 接口(返回播放 URL) fetch(`http://localhost:9000/migu/check?${songInfoJson}`) .then((res) => res.text()) .then((url) => console.log('咪гъ播放链接:', url)) .catch(() => console.log('404: 不可用')); ``` -------------------------------- ### UnblockNeteaseMusic Command-Line Help Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Display help information for the UnblockNeteaseMusic command-line interface, showing available options and their descriptions. ```bash $ unblockneteasemusic -h usage: unblockneteasemusic [-v] [-p http[:https]] [-a address] [-u url] [-f host] [-o source [source ...]] [-t token] [-e url] [-s] [-h] optional arguments: -v, --version output the version number -p port, --port http[:https] specify server port -a address, --address address specify server host -u url, --proxy-url url request through upstream proxy -f host, --force-host host force the netease server ip -o source [source ...], --match-order source [source ...] set priority of sources -t token, --token token set up proxy authentication -e url, --endpoint url replace virtual endpoint with public host -s, --strict enable proxy limitation -c, --cnrelay host:port Mainland China relay to get music url -h, --help output usage information ``` -------------------------------- ### Build and Run UnblockNeteaseMusic Server from Source with Docker Compose Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Clone the repository, navigate to the directory, and use Docker Compose to build and run the server. This method is suitable for development or custom builds. ```bash git clone https://github.com/UnblockNeteaseMusic/server.git UnblockNeteaseMusic cd UnblockNeteaseMusic docker-compose up ``` -------------------------------- ### Create an HTTP/HTTPS proxy server instance Source: https://context7.com/unblockneteasemusic/server/llms.txt Instantiate a proxy server using the `server` module, which supports MITM and CONNECT tunneling. Configure whitelist, blacklist, and authentication for the proxy. The server instances are standard Node.js http/https.Server objects. ```javascript const server = require('./src/server'); // server.http 和 server.https 均为标准 Node.js http/https.Server 实例 // 配置白名单(允许代理的 URL 正则,严格模式下生效) server.whitelist = [ '://[\w.]*music\.126\.net', '://[\w.]*\.netease.com', 'https://music\.163\.com', ]; // 配置黑名单(默认拒绝本地回环地址) server.blacklist = ['://127\.\d+\.\d+\.\d+', '://localhost']; // 设置代理认证(格式:'user:password') server.authentication = 'admin:secret123'; // 启动 HTTP 代理(端口 8080) server.http.listen(8080, '0.0.0.0').once('listening', () => { console.log('HTTP 代理运行在 http://0.0.0.0:8080'); }); // 启动 HTTPS 代理(端口 8081,使用自签证书) server.https.listen(8081, '0.0.0.0').once('listening', () => { console.log('HTTPS 代理运行在 https://0.0.0.0:8081'); }); // 访问 PAC 自动配置脚本 // GET http://localhost:8080/proxy.pac // 返回的 PAC 脚本会自动路由网易云相关域名到本代理 ``` -------------------------------- ### Use `match` function as a library Source: https://context7.com/unblockneteasemusic/server/llms.txt Import and use the `match` function to find playable links for Netease Cloud Music songs from third-party sources. You can specify upstream proxies, force Netease server IPs, or provide known song metadata to optimize the search. ```javascript const match = require('@unblockneteasemusic/server'); // 设置可选的上游代理(如需要) global.proxy = require('url').parse('http://127.0.0.1:1080'); // 强制指定网易云服务器 IP(防止请求死循环) global.hosts = { 'music.163.com': '59.111.181.60' }; // 使用默认音源(kugou, bodian, migu, ytdlp)匹配歌曲 match(418602084) .then((song) => { console.log('匹配成功:', song); // 输出示例: // { // size: 9524280, // br: 320000, // url: 'http://fs.storefront.kugou.com/xxx.mp3', // md5: 'abc123...', // source: 'kugou' // } }) .catch((err) => console.error('未找到可用音源:', err)); // 指定音源优先级顺序 match(418602084, ['qq', 'kuwo', 'migu']) .then((song) => console.log('来源:', song.source, '比特率:', song.br)) .catch(() => console.log('所有指定音源均不可用')); // 传入已知的歌曲元数据,跳过网络查询 const songData = { id: 418602084, name: '告白气球', alias: [], duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], }; match(418602084, null, songData).then((song) => console.log(song.url)); ``` -------------------------------- ### Enable Music Sources with UNM Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Use the `-o` flag followed by the desired source codes to enable them when running UNM. Multiple sources can be enabled at once. ```bash node app.js -o bilibili ytdlp ``` -------------------------------- ### Music Source Providers: Unified check(info) interface Source: https://context7.com/unblockneteasemusic/server/llms.txt Each music source provider exposes a unified `check(info)` method that accepts song metadata and returns a playable audio URL. Supports different providers like Kugou, Migu, and QQ Music, with specific environment variable configurations for enabling features like FLAC and setting cookies. ```javascript const kugou = require('./src/provider/kugou'); const migu = require('./src/provider/migu'); const qq = require('./src/provider/qq'); const songInfo = { id: 418602084, name: '告白气球', duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], keyword: '告白气balloon - 周杰伦', }; // 酷狗音乐(默认启用,支持无损) process.env.ENABLE_FLAC = 'true'; kugou.check(songInfo) .then((url) => console.log('酷狗 URL:', url)) .catch(() => console.log('酷狗不可用')); // 咪咕音乐(需设置 MIGU_COOKIE) process.env.MIGU_COOKIE = 'your_aversionid_here'; migu.check(songInfo) .then((url) => console.log('咪咕 URL:', url)) .catch(() => console.log('咪咕不可用')); // QQ 音乐(需设置 QQ_COOKIE,支持 FLAC) process.env.QQ_COOKIE = 'uin=123456789; qm_keyst=your_qm_keyst'; qq.check(songInfo) .then((url) => console.log('QQ 音乐 URL:', url)) .catch(() => console.log('QQ 音乐不可用')); // 批量并发查询所有可用音源(SELECT_MAX_BR 模式) const { PROVIDERS } = require('./src/consts'); process.env.SELECT_MAX_BR = 'true'; Promise.allSettled( Object.entries(PROVIDERS).map(([name, provider]) => provider.check(songInfo).then((url) => ({ name, url })) ) ).then((results) => { const available = results .filter((r) => r.status === 'fulfilled') .map((r) => r.value); console.log('可用音源:', available.map((s) => s.name).join(', ')); }); ``` -------------------------------- ### Use UnblockNeteaseMusic Server as a Library Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Integrate the server as a library to find matching songs from other platforms. Ensure proxy or hosts are set if needed. ```javascript const match = require('@unblockneteasemusic/server'); /** * Set proxy or hosts if needed */ global.proxy = require('url').parse('http://127.0.0.1:1080'); global.hosts = { 'i.y.qq.com': '59.37.96.220' }; /** * Find matching song from other platforms * @param {Number} id netease song id * @param {Array||undefined} source support qq, xiami, baidu, kugou, kuwo, migu, joox * @return {Promise} */ match(418602084, ['qq', 'kuwo', 'migu']).then(console.log); ``` -------------------------------- ### Run UnblockNeteaseMusic Server via Docker Hub Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Pull and run the UnblockNeteaseMusic server image from Docker Hub. Environment variables and configuration parameters can be passed during runtime. ```bash docker run pan93412/unblock-netease-music-enhanced ``` ```bash docker pull pan93412/unblock-netease-music-enhanced ``` ```bash docker run -e JSON_LOG=true -e LOG_LEVEL=debug pan93412/unblock-netease-music-enhanced ``` ```bash docker run pan93412/unblock-netease-music-enhanced -o kuwo -p 1234 ``` -------------------------------- ### server Module — HTTP/HTTPS Proxy Server Source: https://context7.com/unblockneteasemusic/server/llms.txt Create a proxy server instance that supports MITM and CONNECT tunneling, handling all traffic to and from the Netease Cloud Music client. ```APIDOC ## server Module — HTTP/HTTPS Proxy Server ### Description Create a proxy server instance that supports MITM and CONNECT tunneling, handling all traffic to and from the Netease Cloud Music client. ### Usage ```javascript const server = require('./src/server'); // server.http and server.https are standard Node.js http/https.Server instances // Configure whitelist (allowed URL regex, effective in strict mode) server.whitelist = [ '://[\\w.]*music\\.126\\.net', '://[\\w.]*\\.netease\\.com', 'https://music\\.163\\.com', ]; // Configure blacklist (defaults to rejecting local loopback addresses) server.blacklist = ['://127\\.\\d+\\.\\d+\\.\\d+', '://localhost']; // Set proxy authentication (format: 'user:password') server.authentication = 'admin:secret123'; // Start HTTP proxy (port 8080) server.http.listen(8080, '0.0.0.0').once('listening', () => { console.log('HTTP proxy running on http://0.0.0.0:8080'); }); // Start HTTPS proxy (port 8081, using self-signed certificate) server.https.listen(8081, '0.0.0.0').once('listening', () => { console.log('HTTPS proxy running on https://0.0.0.0:8081'); }); // Access PAC auto-configuration script // GET http://localhost:8080/proxy.pac // The returned PAC script automatically routes Netease Cloud Music related domains to this proxy. ``` ``` -------------------------------- ### Initialize and Use logScope for Scoped Logging Source: https://context7.com/unblockneteasemusic/server/llms.txt Utilize the logScope utility, built on Pino, for scoped logging. This tool supports JSON output and log level control, essential for tracing proxy requests and music source matching. Configure log behavior using environment variables. ```javascript const { logScope } = require('./src/logger'); const logger = logScope('my-module'); // 普通信息日志 logger.info({ songId: 418602084 }, '开始查找音源'); // 调试日志(需设置 LOG_LEVEL=debug) logger.debug({ source: 'kugou', keyword: '告白气球 - 周杰伦' }, '正在搜索...'); // 错误日志 logger.error({ err: new Error('连接超时') }, '酷狗请求失败'); // 通过环境变量控制日志行为 process.env.LOG_LEVEL = 'debug'; // 输出所有日志 process.env.JSON_LOG = 'true'; // 输出机器可读的 JSON 格式 process.env.LOG_FILE = '/var/log/unm.log'; // 输出到文件 // JSON 格式输出示例: // {"level":30,"scope":"my-module","msg":"开始查找音源","songId":418602084} ``` -------------------------------- ### Run Latest Version from Repository Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Clone the repository and run the application directly using Node.js. It is recommended to use a terminal multiplexer like screen or tmux to keep the process running in the background. Updates can be fetched using 'git pull'. ```bash git clone https://github.com/UnblockNeteaseMusic/server.git UnblockNeteaseMusic cd UnblockNeteaseMusic node app.js # 建议使用 screen / tmux 把 app.js 挂后台 ``` ```bash git pull ``` -------------------------------- ### match(id, source?, data?) — Core Matching Function (Library Usage) Source: https://context7.com/unblockneteasemusic/server/llms.txt This is the core external interface of the project, exposed as an npm dependency. It finds available playback links from third-party music sources for a given Netease Cloud Music song ID. ```APIDOC ## match(id, source?, data?) ### Description Finds available playback links from third-party music sources for a given Netease Cloud Music song ID. This is the core external interface of the project, exposed as an npm dependency. ### Parameters * **id** (number) - Required - The Netease Cloud Music song ID. * **source** (string[]) - Optional - An array of preferred music source names in order of priority. * **data** (object) - Optional - Pre-existing song metadata to skip network queries. ### Request Example ```javascript const match = require('@unblockneteasemusic/server'); // Set optional upstream proxy if needed global.proxy = require('url').parse('http://127.0.0.1:1080'); // Force specify Netease Cloud Music server IP to prevent request loops global.hosts = { 'music.163.com': '59.111.181.60' }; // Match song using default sources (kugou, bodian, migu, ytdlp) match(418602084) .then((song) => { console.log('Match successful:', song); // Example output: // { // size: 9524280, // br: 320000, // url: 'http://fs.storefront.kugou.com/xxx.mp3', // md5: 'abc123...', // source: 'kugou' // } }) .catch((err) => console.error('No available source found:', err)); // Specify source priority order match(418602084, ['qq', 'kuwo', 'migu']) .then((song) => console.log('Source:', song.source, 'Bitrate:', song.br)) .catch(() => console.log('All specified sources unavailable')); // Pass known song metadata to skip network queries const songData = { id: 418602084, name: '告白气球', alias: [], duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], }; match(418602084, null, songData).then((song) => console.log(song.url)); ``` ``` -------------------------------- ### Audio Source Providers - check(info) Interface Source: https://context7.com/unblockneteasemusic/server/llms.txt Each audio source provider exposes a unified `check(info)` method that accepts song metadata and returns a playable audio URL. ```APIDOC ## Audio Source Providers - check(info) Interface Each audio source provider exposes a unified `check(info)` method that accepts song metadata and returns a playable audio URL. ### Parameters - **info** (object) - Song metadata object, typically obtained from the `find` function. ### Usage ```javascript const kugou = require('./src/provider/kugou'); const migu = require('./src/provider/migu'); const qq = require('./src/provider/qq'); const songInfo = { id: 418602084, name: '告白气球', duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], keyword: '告白气balloon - 周杰伦', }; // Kugou Music (enabled by default, supports lossless) process.env.ENABLE_FLAC = 'true'; kugou.check(songInfo) .then((url) => console.log('Kugou URL:', url)) .catch(() => console.log('Kugou unavailable')); // Migu Music (requires MIGU_COOKIE setting) process.env.MIGU_COOKIE = 'your_aversionid_here'; migu.check(songInfo) .then((url) => console.log('Migu URL:', url)) .catch(() => console.log('Migu unavailable')); // QQ Music (requires QQ_COOKIE setting, supports FLAC) process.env.QQ_COOKIE = 'uin=123456789; qm_keyst=your_qm_keyst'; qq.check(songInfo) .then((url) => console.log('QQ Music URL:', url)) .catch(() => console.log('QQ Music unavailable')); // Batch concurrent query for all available sources (SELECT_MAX_BR mode) const { PROVIDERS } = require('./src/consts'); process.env.SELECT_MAX_BR = 'true'; Promise.allSettled( Object.entries(PROVIDERS).map(([name, provider]) => provider.check(songInfo).then((url) => ({ name, url })) ) ).then((results) => { const available = results .filter((r) => r.status === 'fulfilled') .map((r) => r.value); console.log('Available sources:', available.map((s) => s.name).join(', ')); }); ``` ``` -------------------------------- ### Enable Loopback Exemption for UWP Apps Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Run this command as administrator to enable loopback for UWP apps, which is necessary due to network isolation limitations. ```powershell checknetisolation loopbackexempt -a -n="1F8B0F94.122165AE053F_j2p0p5q0044a6" ``` -------------------------------- ### CacheStorage: In-memory caching for search results Source: https://context7.com/unblockneteasemusic/server/llms.txt Provides an in-memory cache with expiration for search results to avoid duplicate requests. Default cache duration is 30 minutes, adjustable as needed. Can be completely disabled via environment variable. ```javascript const { CacheStorage, getManagedCacheStorage, CacheStorageGroup } = require('./src/cache'); // 创建一个受 CacheStorageGroup 管理的缓存存储实例 const cs = getManagedCacheStorage('my-module'); cs.aliveDuration = 60 * 60 * 1000; // 设为 1 小时 // 缓存一个异步操作的结果 async function fetchSongUrl(songId) { return cs.cache( songId, // 缓存键(任意类型) async () => { // 实际执行的操作 const response = await fetch(`https://api.example.com/song/${songId}`); return response.json(); }, Date.now() + 30 * 60 * 1000 // 可选:自定义过期时间戳 ); } fetchSongUrl(12345).then((data) => console.log('首次请求(实际执行):', data)); fetchSongUrl(12345).then((data) => console.log('再次请求(命中缓存):', data)); // 获取全局 CacheStorageGroup 单例,手动触发清理 const group = CacheStorageGroup.getInstance(); group.cleanup(); // 清除所有已注册 CacheStorage 中的过期缓存 // 通过环境变量完全禁用缓存 process.env.NO_CACHE = 'true'; ``` -------------------------------- ### Modify Hosts File for Netease Music Source: https://github.com/unblockneteasemusic/server/blob/enhanced/README.md Add these rules to your hosts file to redirect Netease Music domains to your server IP. This method requires listening on port 80. ```hosts music.163.com interface.music.163.com interface3.music.163.com interfacepc.music.163.com interface.music.163.com.163jiasu.com interface3.music.163.com.163jiasu.com ``` -------------------------------- ### find(id, data?) Source: https://context7.com/unblockneteasemusic/server/llms.txt Retrieves formatted song metadata (name, artist, album, duration, search keyword) based on the Netease Cloud Music song ID. Results are automatically cached. ```APIDOC ## find(id, data?) Retrieves formatted song metadata (name, artist, album, duration, search keyword) based on the Netease Cloud Music song ID. Results are automatically cached. ### Parameters - **id** (number) - The Netease Cloud Music song ID. - **data** (object, optional) - Pre-existing song data to format, skipping network request. ### Usage ```javascript const find = require('./src/provider/find'); // Get metadata from Netease Cloud Music API by song ID find(418602084) .then((info) => { console.log(info); // Output: // { // id: 418602084, // name: '告白气球', // alias: [], // duration: 215160, // album: { id: 34795, name: '周杰伦的床边故事' }, // artists: [{ id: 6452, name: '周杰伦' }], // keyword: '告白气球 - 周杰伦' // Keyword for cross-platform search // } }) .catch(() => console.log('Song not found or network error')); // Format existing data directly (skip network request) const rawData = { id: 418602084, name: '告白气球(cover:xxx)', // 'cover' identifier will be removed alias: [], duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], }; find(418602084, rawData).then((info) => { console.log('Cleaned name:', info.name); // '告白气球' console.log('Search keyword:', info.keyword); // '告白气球 - 周杰伦' }); // Enable album name enhancement for search process.env.SEARCH_ALBUM = 'true'; find(418602084).then((info) => { console.log('Keyword with album:', info.keyword); // '告白气球 - 周杰伦 周杰伦的床边故事' }); ``` ``` -------------------------------- ### Utilize `hook` module for request interception Source: https://context7.com/unblockneteasemusic/server/llms.txt The `hook` module intercepts and modifies requests/responses to Netease Cloud Music servers. It handles decryption, IP injection, URL replacement, and VIP unlocking. Control behavior using environment variables. ```javascript const hook = require('./src/hook'); // hook.target.host — 需要被代理拦截的网易云域名集合 console.log([...hook.target.host]); // ['music.163.com', 'interface.music.163.com', 'interface3.music.163.com', ...] // hook.target.path — 需要被拦截处理的 API 路径集合 console.log([...hook.target.path]); // ['/api/song/enhance/player/url', '/api/song/enhance/download/url', ...] // hook.request.before(ctx) — 请求发出前的处理 // 自动完成:解密 eapi/linuxapi/api 加密体,注入 X-Real-IP: 118.88.88.88, // 屏蔽广告(BLOCK_ADS=true),屏蔽更新检测(DISABLE_UPGRADE_CHECK=true) // hook.request.after(ctx) — 收到响应后的处理 // 自动完成:解密响应体,替换变灰歌曲 URL,注入本地 VIP 信息, // 解除音效/歌词特效限制 // 环境变量控制示例 process.env.ENABLE_LOCAL_VIP = 'svip'; // 激活本地超级 VIP process.env.BLOCK_ADS = 'true'; // 屏蔽客户端广告 process.env.DISABLE_UPGRADE_CHECK = 'true'; // 禁用更新检测 process.env.ENABLE_FLAC = 'true'; // 启用无损音质获取 process.env.SELECT_MAX_BR = 'true'; // 选择所有音源中最高码率 process.env.FOLLOW_SOURCE_ORDER = 'true'; // 严格按音源顺序依次查找 process.env.MIN_BR = '320000'; // 最低可接受码率(bps) process.env.NO_CACHE = 'true'; // 禁用缓存 process.env.NETEASE_COOKIE = 'MUSIC_U=007554xxx'; // 注入网易云 Cookie ``` -------------------------------- ### Song Metadata Query: Formatted song metadata by ID Source: https://context7.com/unblockneteasemusic/server/llms.txt Retrieves formatted song metadata (name, artist, album, duration, search keywords) based on NetEase Cloud Music song ID. Results are automatically cached. Can also format existing data directly, skipping network requests. ```javascript const find = require('./src/provider/find'); // 通过歌曲 ID 从网易云 API 获取元数据 find(418602084) .then((info) => { console.log(info); // 输出: // { // id: 418602084, // name: '告白气球', // alias: [], // duration: 215160, // album: { id: 34795, name: '周杰伦的床边故事' }, // artists: [{ id: 6452, name: '周杰伦' }], // keyword: '告白气球 - 周杰伦' // 用于跨平台搜索的关键词 // } }) .catch(() => console.log('歌曲不存在或网络异常')); // 传入已有数据直接格式化(跳过网络请求) const rawData = { id: 418602084, name: '告白气球(cover:xxx)', // cover 标识会被自动去除 alias: [], duration: 215160, album: { id: 34795, name: '周杰伦的床边故事' }, artists: [{ id: 6452, name: '周杰伦' }], }; find(418602084, rawData).then((info) => { console.log('清洗后的名称:', info.name); // '告白气球' console.log('搜索关键词:', info.keyword); // '告白气球 - 周杰伦' }); // 启用专辑名称增强搜索 process.env.SEARCH_ALBUM = 'true'; find(418602084).then((info) => { console.log('含专辑的关键词:', info.keyword); // '告白气球 - 周杰伦 周杰伦的床边故事' }); ``` -------------------------------- ### CacheStorage Class Source: https://context7.com/unblockneteasemusic/server/llms.txt Provides an in-memory cache with expiration times for search results, preventing duplicate requests. The default cache duration is 30 minutes, which can be adjusted. ```APIDOC ## CacheStorage Class Provides an in-memory cache with expiration times for search results, preventing duplicate requests. The default cache duration is 30 minutes, which can be adjusted. ### Usage ```javascript const { CacheStorage, getManagedCacheStorage, CacheStorageGroup } = require('./src/cache'); // Create a managed cache storage instance const cs = getManagedCacheStorage('my-module'); cs.aliveDuration = 60 * 60 * 1000; // Set to 1 hour // Cache the result of an asynchronous operation async function fetchSongUrl(songId) { return cs.cache( songId, // Cache key (any type) async () => { // Actual operation to perform const response = await fetch(`https://api.example.com/song/${songId}`); return response.json(); }, Date.now() + 30 * 60 * 1000 // Optional: Custom expiration timestamp ); } fetchSongUrl(12345).then((data) => console.log('First request (actual execution):', data)); fetchSongUrl(12345).then((data) => console.log('Second request (cache hit):', data)); // Get the global CacheStorageGroup singleton to manually trigger cleanup const group = CacheStorageGroup.getInstance(); group.cleanup(); // Clear expired caches in all registered CacheStorage instances // Completely disable cache via environment variable process.env.NO_CACHE = 'true'; ``` ``` -------------------------------- ### request(method, url, headers?, body?, proxy?) Source: https://context7.com/unblockneteasemusic/server/llms.txt A universal HTTP request function that wraps Node.js's native http/https modules. It supports automatic redirection, gzip/deflate/brotli decompression, upstream proxy tunneling, and request cancellation. ```APIDOC ## request(method, url, headers?, body?, proxy?) A universal HTTP request function that wraps Node.js's native http/https modules. It supports automatic redirection, gzip/deflate/brotli decompression, upstream proxy tunneling, and request cancellation. ### Parameters - **method** (string) - The HTTP method (e.g., 'GET', 'POST'). - **url** (string) - The URL to request. - **headers** (object, optional) - Custom request headers. - **body** (string | object, optional) - The request body. - **proxy** (URL, optional) - An upstream proxy URL to use for the request. ### Usage ```javascript const request = require('./src/request'); // Basic GET request with automatic response decompression request('GET', 'https://music.163.com/api/song/detail?ids=[418602084]') .then((response) => response.json()) .then((data) => console.log('Song Info:', data.songs[0].name)) .catch((err) => console.error('Request failed:', err.message)); // POST request with custom headers request( 'POST', 'https://u.y.qq.com/cgi-bin/musicu.fcg', { 'Content-Type': 'application/json', Cookie: 'uin=123456; qm_keyst=xxx', }, JSON.stringify({ req: { module: 'music.search.SearchCgiService' } }) ) .then((response) => response.json()) .then((data) => console.log('QQ Search Results:', data)) .catch(console.error); // Make a request via an upstream proxy (for accessing overseas audio sources like YouTube) const proxyUrl = require('url').parse('http://127.0.0.1:7890'); request('GET', 'https://www.googleapis.com/youtube/v3/search', {}, null, proxyUrl) .then((response) => response.json()) .then((data) => console.log('YouTube Search Results:', data)); // Read raw Buffer response body (for audio data detection) request('GET', 'https://some-music-url.mp3', { range: 'bytes=0-8191' }) .then((response) => response.body(true)) // true = return Buffer .then((buffer) => console.log('First 4 bytes:', buffer.slice(0, 4).toString())) .catch(console.error); ``` ``` -------------------------------- ### hook Module — Request Interception Hooks Source: https://context7.com/unblockneteasemusic/server/llms.txt Intercept and modify requests/responses to Netease Cloud Music servers, including core logic like decrypting eapi/linuxapi encrypted requests, injecting real IP, and replacing song links. ```APIDOC ## hook Module — Request Interception Hooks ### Description Intercept and modify requests/responses to Netease Cloud Music servers, including core logic like decrypting eapi/linuxapi encrypted requests, injecting real IP, and replacing song links. ### Usage ```javascript const hook = require('./src/hook'); // hook.target.host — Set of Netease Cloud Music domains to be intercepted by the proxy console.log([...hook.target.host]); // ['music.163.com', 'interface.music.163.com', 'interface3.music.163.com', ...] // hook.target.path — Set of API paths to be intercepted and processed console.log([...hook.target.path]); // ['/api/song/enhance/player/url', '/api/song/enhance/download/url', ...] // hook.request.before(ctx) — Processing before a request is sent // Automatically performs: decryption of eapi/linuxapi/api encrypted bodies, injection of X-Real-IP: 118.88.88.88, // ad blocking (BLOCK_ADS=true), and disabling upgrade checks (DISABLE_UPGRADE_CHECK=true). // hook.request.after(ctx) — Processing after a response is received // Automatically performs: response decryption, replacement of grayed-out song URLs, injection of local VIP information, // and removal of restrictions on sound effects/lyric effects. // Environment variable control examples process.env.ENABLE_LOCAL_VIP = 'svip'; // Activate local super VIP process.env.BLOCK_ADS = 'true'; // Block client ads process.env.DISABLE_UPGRADE_CHECK = 'true'; // Disable upgrade checks process.env.ENABLE_FLAC = 'true'; // Enable lossless quality retrieval process.env.SELECT_MAX_BR = 'true'; // Select the highest bitrate from all sources process.env.FOLLOW_SOURCE_ORDER = 'true'; // Strictly follow source order for lookup process.env.MIN_BR = '320000'; // Minimum acceptable bitrate (bps) process.env.NO_CACHE = 'true'; // Disable caching process.env.NETEASE_COOKIE = 'MUSIC_U=007554xxx'; // Inject Netease Cloud Music Cookie ``` ``` -------------------------------- ### HTTP Request Utility: General-purpose request function Source: https://context7.com/unblockneteasemusic/server/llms.txt Encapsulates Node.js native http/https modules for general request functions. Supports automatic redirection, gzip/deflate/brotli decompression, upstream proxy penetration, and request cancellation. Can read raw Buffer responses. ```javascript const request = require('./src/request'); // 基本 GET 请求,自动解压响应 request('GET', 'https://music.163.com/api/song/detail?ids=[418602084]') .then((response) => response.json()) .then((data) => console.log('歌曲信息:', data.songs[0].name)) .catch((err) => console.error('请求失败:', err.message)); // POST 请求,携带自定义请求头 request( 'POST', 'https://u.y.qq.com/cgi-bin/musicu.fcg', { 'Content-Type': 'application/json', Cookie: 'uin=123456; qm_keyst=xxx', }, JSON.stringify({ req: { module: 'music.search.SearchCgiService' } }) ) .then((response) => response.json()) .then((data) => console.log('QQ 搜索结果:', data)) .catch(console.error); // 通过上游代理发起请求(用于访问 YouTube 等境外音源) const proxyUrl = require('url').parse('http://127.0.0.1:7890'); request('GET', 'https://www.googleapis.com/youtube/v3/search', {}, null, proxyUrl) .then((response) => response.json()) .then((data) => console.log('YouTube 搜索结果:', data)); // 读取原始 Buffer 响应体(用于音频数据检测) request('GET', 'https://some-music-url.mp3', { range: 'bytes=0-8191' }) .then((response) => response.body(true)) // true = 返回 Buffer .then((buffer) => console.log('前 4 字节:', buffer.slice(0, 4).toString())) .catch(console.error); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.