mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-10-21 07:01:23 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae1197f552 | ||
|
|
3e8273780a | ||
|
|
e866ead286 | ||
|
|
eee3daa2d9 | ||
|
|
8efe78a3a3 | ||
|
|
04510ab4ae | ||
|
|
36411fb613 | ||
|
|
355057c56e | ||
|
|
da9d8822fc | ||
|
|
2d8b2e27e4 | ||
|
|
f108803509 | ||
|
|
563c491dad | ||
|
|
6a460caba5 | ||
|
|
890ce471a5 | ||
|
|
64aa95532e |
@@ -1,14 +0,0 @@
|
|||||||
/**
|
|
||||||
!/module
|
|
||||||
!/plugins
|
|
||||||
!/public
|
|
||||||
!/static
|
|
||||||
!/util
|
|
||||||
!/app.js
|
|
||||||
!/server.js
|
|
||||||
!/package.json
|
|
||||||
!/package-lock.json
|
|
||||||
!/index.js
|
|
||||||
!/generateConfig.js
|
|
||||||
!/main.js
|
|
||||||
!/data
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
# EditorConfig is awesome: http://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
|
||||||
|
|
||||||
# Unix-style newlines with a newline ending every file
|
|
||||||
[*]
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
# Matches multiple files with brace expansion notation
|
|
||||||
# Set default charset
|
|
||||||
[*.{js,py}]
|
|
||||||
charset = utf-8
|
|
||||||
|
|
||||||
# 4 space indentation
|
|
||||||
[*.py]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
# Tab indentation (no size specified)
|
|
||||||
[Makefile]
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
# Indentation override for all JS under lib directory
|
|
||||||
[*.{js,ts}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# Matches the exact files either package.json or .travis.yml
|
|
||||||
[{package.json,.travis.yml}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
### CORS资源共享设置
|
|
||||||
## 如果你需要配置, 请取消下面的注释并设置具体的域名
|
|
||||||
# CORS_ALLOW_ORIGIN = "*"
|
|
||||||
|
|
||||||
### 代理设置
|
|
||||||
## 启用反向代理
|
|
||||||
ENABLE_PROXY = false
|
|
||||||
## 代理配置
|
|
||||||
PROXY_URL = "https://your-proxy-url.com/?proxy="
|
|
||||||
|
|
||||||
|
|
||||||
### UnblockNeteaseMusic 设置项
|
|
||||||
## 启用全局解灰, 无论是否调用参数都会使用解灰(推荐开启)
|
|
||||||
ENABLE_GENERAL_UNBLOCK = true
|
|
||||||
## 歌曲启用无损音质
|
|
||||||
ENABLE_FLAC = true
|
|
||||||
## 启用无损音质时,是否选择音质最高的
|
|
||||||
SELECT_MAX_BR = true
|
|
||||||
## 音源设置
|
|
||||||
UNBLOCK_SOURCE = pyncmd,qq,kuwo,migu,kugou
|
|
||||||
## 严格按照配置音源设置顺序进行匹配
|
|
||||||
FOLLOW_SOURCE_ORDER = true
|
|
||||||
## Cookie设置项; 推荐在Vercel等平台进行环境变量的设置或者设置github secret
|
|
||||||
# 网易云 cookie
|
|
||||||
# 格式:MUSIC_U=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
||||||
NETEASE_COOKIE = ""
|
|
||||||
# JOOX cookie
|
|
||||||
# 格式:JOOX_COOKIE="wmid=<your_wmid>; session_key=<your_session_key>"
|
|
||||||
JOOX_COOKIE = ""
|
|
||||||
# 咪咕 cookie
|
|
||||||
# 格式:MIGU_COOKIE="<your_aversionid>"
|
|
||||||
MIGU_COOKIE = ""
|
|
||||||
# qq cookie
|
|
||||||
# 格式:QQ_COOKIE="uin=<your_uin>; qm_keyst=<your_qm_keyst>"
|
|
||||||
QQ_COOKIE = ""
|
|
||||||
# Youtube 密钥
|
|
||||||
# 格式:YOUTUBE_KEY="<your_data_api_key>"
|
|
||||||
YOUTUBE_KEY = ""
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
|
|
||||||
ignorePatterns: ['public/'],
|
|
||||||
parserOptions: {
|
|
||||||
parser: 'babel-eslint',
|
|
||||||
ecmaVersion: 2018,
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
plugins: ['html'],
|
|
||||||
extends: ['plugin:prettier/recommended'],
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
'prettier/prettier': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
endOfLine: 'auto',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
indent: ['error', 2, { SwitchCase: 1 }],
|
|
||||||
'space-infix-ops': ['error', { int32Hint: false }],
|
|
||||||
'key-spacing': [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
beforeColon: false,
|
|
||||||
afterColon: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-octal': 2,
|
|
||||||
'no-redeclare': 2,
|
|
||||||
'comma-spacing': 2,
|
|
||||||
'no-new-object': 2,
|
|
||||||
'arrow-spacing': 2,
|
|
||||||
quotes: [
|
|
||||||
2,
|
|
||||||
'single',
|
|
||||||
{
|
|
||||||
avoidEscape: true,
|
|
||||||
allowTemplateLiterals: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['**/*.ts'],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
extends: [
|
|
||||||
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
|
|
||||||
// 'prettier/@typescript-eslint',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
---
|
|
||||||
name: 创建问题反馈
|
|
||||||
about: 问题反馈
|
|
||||||
title: "<不按照模版格式或者删除模版信息将得不到处理,确认看完了调用前须知再发 issues>"
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 环境
|
|
||||||
- 系统/平台: <你的系统和平台>
|
|
||||||
|
|
||||||
- nodejs 版本: <你的 NodeJS 版本号>
|
|
||||||
|
|
||||||
- API版本: <运行的云音乐 API 的版本号, 对应 package.json 里面的 version>
|
|
||||||
|
|
||||||
## 出现问题
|
|
||||||
<请清晰描述出现的问题,不要使用xxx不行之类的模糊不清的语句,我没有读心术>
|
|
||||||
|
|
||||||
## 重现步骤
|
|
||||||
<请清晰描述重现步骤,调用的接口链接和参数以及命令行错误信息,最好贴上截图(命令行错误信息和接口返回内容)>
|
|
||||||
|
|
||||||
## 期待效果
|
|
||||||
<请清晰描述现在的效果和期待的效果>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
>注意: 如果解灰出现问题, 本项目只是集成[UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server)的接口, 请在对应的仓库开启议题
|
|
||||||
|
|
||||||
>维护项目都是业余时间,精力有限,我只能挑容易解决的issues处理,为了节约双方时间,请尽可能提供足够的有用的信息,给的信息不够我只能根据精力和时间看情况处理,如果模板信息看都不看就删掉,我不会进行任何回复,并且一个月后close掉issue
|
|
||||||
|
|
||||||
>先看文档有没有相关说明,调用前须知必看,确认看完了调用前须知再发 issues
|
|
||||||
|
|
||||||
>先在 issues 搜一下是否有相似问题,没有再发,否则直接关闭
|
|
||||||
|
|
||||||
>不处理别人搭建的线上服务的问题,此项目提供任何线上服务不保证质量,请自行搭建
|
|
||||||
|
|
||||||
>重现步骤尽量详细,不能含糊不清,包含请求地址和对应参数以及操作过程描述,不是每个人都喜欢猜别人遇到了什么问题和找参数一个个试,也比较浪费时间
|
|
||||||
|
|
||||||
>如果不是提建议,提 issues 如果不照着模版来将不会优先处理或放着不管
|
|
||||||
|
|
||||||
>460 cheating 的问题把 `utils/request.js` 里面的 `headers['X-Real-IP']` 的注释取消掉就好
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
name: 功能需求
|
|
||||||
about: 希望添加新接口
|
|
||||||
title: ''
|
|
||||||
labels: 功能需求
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**功能描述**
|
|
||||||
- 请清晰描述你所希望添加的功能,最好贴上对应客户端界面的截图
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
name: Build Image
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- v*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
if: github.event.base_ref == 'refs/heads/main'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Build image job
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout main
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Get version
|
|
||||||
id: get_version
|
|
||||||
if: startsWith(github.ref, 'refs/tags/') && startsWith(github.repository, 'Binaryify/ncm')
|
|
||||||
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
- name: Build and publish image
|
|
||||||
uses: elgohr/Publish-Docker-Github-Action@v5
|
|
||||||
if: startsWith(github.ref, 'refs/tags/') && startsWith(github.repository, 'Binaryify/ncm')
|
|
||||||
with:
|
|
||||||
name: binaryify/netease_cloud_music_api # dockerid/imageName
|
|
||||||
platforms: linux/arm64,linux/amd64 # 你准备构建的镜像平台
|
|
||||||
tags: latest,${{ steps.get_version.outputs.VERSION }}
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }} # docker hub userid 在setting创建secrets name=DOCKER_USERNAME value=dockerid
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }} # docker hub password,在setting创建secrets name=DOCKER_PASSWORD value=dockerpassword
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
name: Node.js CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [ main ]
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [14.x, 16.x, 18.x ]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-node-
|
|
||||||
- run: npm ci
|
|
||||||
name: Install dependencies
|
|
||||||
- name: Test
|
|
||||||
env:
|
|
||||||
NCM_API_TEST_LOGIN_COUNTRY_CODE: ${{ secrets.NCM_API_TEST_LOGIN_COUNTRY_CODE }}
|
|
||||||
NCM_API_TEST_LOGIN_PHONE: ${{ secrets.NCM_API_TEST_LOGIN_PHONE }}
|
|
||||||
NCM_API_TEST_LOGIN_PASSWORD: ${{ secrets.NCM_API_TEST_LOGIN_PASSWORD }}
|
|
||||||
run: npm test
|
|
||||||
lint:
|
|
||||||
name: Lint
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [14.x]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-node-
|
|
||||||
- run: npm ci
|
|
||||||
name: Install dependencies
|
|
||||||
- name: Lint
|
|
||||||
run: npm run lint
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
# .github/workflows/release.yml
|
|
||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# 发布到 NPM Registry
|
|
||||||
- name: Setup Node.js for NPM
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
registry-url: 'https://registry.npmjs.org/'
|
|
||||||
- run: npm install
|
|
||||||
- name: Publish to NPM
|
|
||||||
run: npm publish --access public
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
||||||
|
|
||||||
# 发布到 GitHub Packages
|
|
||||||
- name: Setup Node.js for GitHub Packages
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
registry-url: 'https://npm.pkg.github.com'
|
|
||||||
- name: Update package name for GitHub Packages
|
|
||||||
run: |
|
|
||||||
json=`cat package.json`
|
|
||||||
echo "$json" | jq '.name = "@neteasecloudmusicapienhanced/api"' > package.json
|
|
||||||
- name: Publish to GitHub Packages
|
|
||||||
run: npm publish --access public
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{ github.token }}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
name: Upstream Sync
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 4 * * *" # At 12PM UTC+8
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
sync_latest_from_upstream:
|
|
||||||
name: Sync latest commits from upstream repo
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.event.repository.fork }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# Step 1: run a standard checkout action
|
|
||||||
- name: Checkout target repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
# Step 2: run the sync action
|
|
||||||
- name: Sync upstream changes
|
|
||||||
id: sync
|
|
||||||
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.1
|
|
||||||
with:
|
|
||||||
upstream_sync_repo: NeteaseCloudMusicApiEnhanced/api-enhanced
|
|
||||||
upstream_sync_branch: main
|
|
||||||
target_sync_branch: main
|
|
||||||
target_repo_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Sync check
|
|
||||||
if: failure()
|
|
||||||
run: |
|
|
||||||
echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork."
|
|
||||||
exit 1
|
|
||||||
+1
-10
@@ -1,10 +1 @@
|
|||||||
.DS_Store
|
node_modules/
|
||||||
node_modules
|
|
||||||
*.log
|
|
||||||
.idea
|
|
||||||
.vscode
|
|
||||||
.history
|
|
||||||
examples/moddef.json
|
|
||||||
bin
|
|
||||||
anonymous_token
|
|
||||||
.vercel
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
node_modules
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"semi": false,
|
|
||||||
"trailingComma": "all",
|
|
||||||
"singleQuote": true
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
|
|
||||||
node_js:
|
|
||||||
- 12
|
|
||||||
-1393
File diff suppressed because it is too large
Load Diff
-16
@@ -1,16 +0,0 @@
|
|||||||
FROM node:lts-alpine
|
|
||||||
|
|
||||||
RUN apk add --no-cache tini
|
|
||||||
|
|
||||||
ENV NODE_ENV production
|
|
||||||
USER node
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY --chown=node:node . ./
|
|
||||||
|
|
||||||
RUN yarn --network-timeout=100000
|
|
||||||
|
|
||||||
EXPOSE 3000
|
|
||||||
|
|
||||||
CMD [ "/sbin/tini", "--", "node", "app.js" ]
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2013-2022 Binaryify
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
# 网易云音乐 API Enhanced
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 项目简介
|
|
||||||
|
|
||||||
本项目为网易云音乐第三方 Node.js API,基于社区停更的原版 API 持续维护和升级,支持丰富的音乐相关接口,适合自建服务、二次开发和多平台部署(如果原版诈尸, 我会及时同步 or 归档)。
|
|
||||||
|
|
||||||
## 快速开始
|
|
||||||
|
|
||||||
### 环境要求
|
|
||||||
|
|
||||||
- Node.js 14 及以上
|
|
||||||
- 推荐使用 pnpm 进行依赖管理
|
|
||||||
|
|
||||||
### 安装
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/neteasecloudmusicapienhanced/api-enhanced.git
|
|
||||||
cd api
|
|
||||||
pnpm i
|
|
||||||
```
|
|
||||||
|
|
||||||
### 启动服务
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 默认端口 3000
|
|
||||||
node app.js
|
|
||||||
|
|
||||||
# 指定端口(如 4000)
|
|
||||||
PORT=4000 node app.js # Mac/Linux
|
|
||||||
set PORT=4000 && node app.js # Windows
|
|
||||||
```
|
|
||||||
|
|
||||||
### 重要提示
|
|
||||||
|
|
||||||
- 调用前请务必阅读文档的 [调用前须知](https://music-api.focalors.ltd/#/?id=%e8%b0%83%e7%94%a8%e5%89%8d%e9%a1%bb%e7%9f%a5) 部分。
|
|
||||||
- 推荐将敏感信息(如 cookie)通过部署平台的环境变量进行配置。
|
|
||||||
|
|
||||||
## 在线体验与文档
|
|
||||||
|
|
||||||
- [在线文档](https://music-api.focalors.ltd/)
|
|
||||||
- [NPM 包地址](https://www.npmjs.com/package/@neteaseapireborn/api)
|
|
||||||
|
|
||||||
## 常见部署方式
|
|
||||||
|
|
||||||
- 推荐参考[在线文档](https://music-api.focalors.ltd/)
|
|
||||||
|
|
||||||
### Vercel 一键部署
|
|
||||||
|
|
||||||
1. fork 本项目
|
|
||||||
2. 在 Vercel 官网新建项目,导入 fork 的仓库
|
|
||||||
3. 直接 Deploy
|
|
||||||
|
|
||||||
### 腾讯云 Serverless 部署
|
|
||||||
|
|
||||||
1. fork 本项目
|
|
||||||
2. 在腾讯云 serverless 控制台新建 Web 应用,选择 Express 框架
|
|
||||||
3. 代码仓库选择 fork 的项目,启动文件填写:
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
export PORT=9000
|
|
||||||
/var/lang/node16/bin/node app.js
|
|
||||||
```
|
|
||||||
4. 完成部署后,访问 API 网关的 URL 即可
|
|
||||||
|
|
||||||
## Node.js 方式调用
|
|
||||||
|
|
||||||
支持直接在 Node.js 项目中引入和调用,返回 Promise:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { login_cellphone, user_cloud } = require('@neteaseapireborn/api')
|
|
||||||
async function main() {
|
|
||||||
const result = await login_cellphone({ phone: '手机号', password: '密码' })
|
|
||||||
console.log(result)
|
|
||||||
const result2 = await user_cloud({ cookie: result.body.cookie })
|
|
||||||
console.log(result2.body)
|
|
||||||
}
|
|
||||||
main()
|
|
||||||
```
|
|
||||||
|
|
||||||
## TypeScript 支持
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { banner } from '@neteaseapireborn/api'
|
|
||||||
banner({ type: 0 }).then((res) => console.log(res))
|
|
||||||
```
|
|
||||||
|
|
||||||
## 单元测试
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test
|
|
||||||
```
|
|
||||||
|
|
||||||
## 主要功能特性
|
|
||||||
|
|
||||||
- 登录/注册/验证码
|
|
||||||
- 用户信息、歌单、动态、播放记录
|
|
||||||
- 歌曲、专辑、歌手、MV、歌词、评论、排行榜
|
|
||||||
- 搜索、推荐、私人 FM、签到、云盘
|
|
||||||
- 歌曲解锁(解灰)、多音源支持(qq/kuwo/kugou/migu/pyncmd)
|
|
||||||
> 注意: 如果解灰出现问题, 本项目只是集成[UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server)的接口, 请在对应的仓库开启议题
|
|
||||||
- 详细接口请见[在线文档](https://music-api.focalors.ltd/)
|
|
||||||
|
|
||||||
## 贡献与社区
|
|
||||||
|
|
||||||
- 欢迎提交 PR、Issue 参与维护
|
|
||||||
|
|
||||||
## SDK 生态
|
|
||||||
|
|
||||||
| 语言 | 作者 | 地址 | 类型 |
|
|
||||||
| ------ | ------------------------------------------- | ---------------------------------------------------------------------------------------- | ------ |
|
|
||||||
| Java | [JackuXL](https://github.com/JackuXL) | [NeteaseCloudMusicApi-SDK](https://github.com/JackuXL/NeteaseCloudMusicApi-SDK) | 第三方 |
|
|
||||||
| Java | [1015770492](https://github.com/1015770492) | https://github.com/1015770492/yumbo-music-utils | 第三方 |
|
|
||||||
| Python | [盧瞳](https://github.com/2061360308) | [NeteaseCloudMusic_PythonSDK](https://github.com/2061360308/NeteaseCloudMusic_PythonSDK) | 第三方 |
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[MIT License](https://github.com/IamFurina/NeteaseCloudMusicApiReborn/blob/main/LICENSE)
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
## 这是什么
|
||||||
|
这是网易云音乐api enhanced的文档页面
|
||||||
|
|
||||||
|
## [前往](https://docs-neteasecloudmusicapi.focalors.ltd)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# NeteaseCloudMusicAPI Enhanced
|
||||||
|
|
||||||
|
> 🎉 全网收集最全的网易云音乐api接口 基于[NeteaseCloudMusicAPI](https://github.com/binaryify/NeteaseCloudMusicApi)的复刻版本
|
||||||
|
|
||||||
|
- ⚡ 四种加密模式 · 后端代理
|
||||||
|
- 🪛 具备多达200多个接口
|
||||||
|
- 📄 更完善的文档
|
||||||
|
|
||||||
|
|
||||||
|
[Github](https://github.com/neteasecloudmusicapienhanced/api-enhanced)
|
||||||
|
[前往本家](https://github.com/binaryify/NeteaseCloudMusicApi)
|
||||||
|
[快速开始](#neteasecloudmusicapienhanced)
|
||||||
|
|
||||||
|

|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const tmpPath = require('os').tmpdir()
|
|
||||||
|
|
||||||
async function start() {
|
|
||||||
// 检测是否存在 anonymous_token 文件,没有则生成
|
|
||||||
if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) {
|
|
||||||
fs.writeFileSync(path.resolve(tmpPath, 'anonymous_token'), '', 'utf-8')
|
|
||||||
}
|
|
||||||
// 启动时更新anonymous_token
|
|
||||||
const generateConfig = require('./generateConfig')
|
|
||||||
await generateConfig()
|
|
||||||
require('./server').serveNcmApi({
|
|
||||||
checkVersion: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
start()
|
|
||||||
-24641
File diff suppressed because it is too large
Load Diff
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"functions": [
|
|
||||||
{
|
|
||||||
"path": "/(.*)",
|
|
||||||
"method": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
||||||
"handler": "index.js",
|
|
||||||
"headers": {
|
|
||||||
"Access-Control-Allow-Credentials": "true",
|
|
||||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
||||||
"Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
const fsPromises = require('fs/promises')
|
|
||||||
const path = require('path')
|
|
||||||
const server = require('../server')
|
|
||||||
const logger = require('../util/logger.js')
|
|
||||||
|
|
||||||
const exportFile = path.join(__dirname, 'moddef.json')
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const def = await server.getModulesDefinitions(
|
|
||||||
path.join(__dirname, '..', 'module'),
|
|
||||||
{
|
|
||||||
'daily_signin.js': '/daily_signin',
|
|
||||||
'fm_trash.js': '/fm_trash',
|
|
||||||
'personal_fm.js': '/personal_fm',
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
|
|
||||||
fsPromises.writeFile(exportFile, JSON.stringify(def, null, 4))
|
|
||||||
logger.info(`👍 Get your own definition at: ${exportFile}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -1,24 +0,0 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const { register_anonimous } = require('./main')
|
|
||||||
const { cookieToJson, generateRandomChineseIP } = require('./util/index')
|
|
||||||
const tmpPath = require('os').tmpdir()
|
|
||||||
|
|
||||||
async function generateConfig() {
|
|
||||||
global.cnIp = generateRandomChineseIP()
|
|
||||||
try {
|
|
||||||
const res = await register_anonimous()
|
|
||||||
const cookie = res.body.cookie
|
|
||||||
if (cookie) {
|
|
||||||
const cookieObj = cookieToJson(cookie)
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.resolve(tmpPath, 'anonymous_token'),
|
|
||||||
cookieObj.MUSIC_A,
|
|
||||||
'utf-8',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports = generateConfig
|
|
||||||
|
Before Width: | Height: | Size: 858 KiB After Width: | Height: | Size: 858 KiB |
+143
@@ -0,0 +1,143 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="KEYWords" contect="网易云音乐,网易云音乐 api,网易云音乐 nodejs,网易云音乐 node.js">
|
||||||
|
<meta name="description" content="网易云音乐 NodeJS API Enhanced">
|
||||||
|
<title>网易云音乐 NodeJS API Enhanced</title>
|
||||||
|
<link rel="icon" href="netease.png">
|
||||||
|
<meta name="description" content="Description">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta name="referrer" content="never">
|
||||||
|
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css" id="theme-css">
|
||||||
|
<style>
|
||||||
|
.theme-toggle {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 24px;
|
||||||
|
right: 24px;
|
||||||
|
z-index: 999;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
background: rgba(30, 30, 46, 0.75);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
outline: none;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 1;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:hover {
|
||||||
|
transform: scale(1.12) rotate(12deg);
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:active {
|
||||||
|
transform: scale(0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle.light {
|
||||||
|
background: rgba(255, 255, 255, 0.85);
|
||||||
|
color: #333;
|
||||||
|
border-color: rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
.sidebar,
|
||||||
|
.content,
|
||||||
|
.markdown-section,
|
||||||
|
.sidebar-nav,
|
||||||
|
.search,
|
||||||
|
.docsify-pagination-container {
|
||||||
|
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||||||
|
<script>
|
||||||
|
(adsbygoogle = window.adsbygoogle || []).push({
|
||||||
|
google_ad_client: "ca-pub-5159844745975514",
|
||||||
|
enable_page_level_ads: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme">🌙</button>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var STORAGE_KEY = 'docsify-theme';
|
||||||
|
var link = document.getElementById('theme-css');
|
||||||
|
var btn = document.getElementById('themeToggle');
|
||||||
|
var LIGHT_URL = '//unpkg.com/docsify/lib/themes/vue.css';
|
||||||
|
var DARK_URL = '//unpkg.com/docsify/lib/themes/dark.css';
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
link.href = theme === 'dark' ? DARK_URL : LIGHT_URL;
|
||||||
|
btn.textContent = theme === 'dark' ? '☀️' : '🌙';
|
||||||
|
btn.className = 'theme-toggle' + (theme === 'dark' ? '' : ' light');
|
||||||
|
localStorage.setItem(STORAGE_KEY, theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTheme() {
|
||||||
|
var isDark = link.href.includes('dark');
|
||||||
|
setTheme(isDark ? 'light' : 'dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
var saved = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (saved) {
|
||||||
|
setTheme(saved);
|
||||||
|
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
setTheme('dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.addEventListener('click', toggleTheme);
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function (e) {
|
||||||
|
if (!localStorage.getItem(STORAGE_KEY)) {
|
||||||
|
setTheme(e.matches ? 'dark' : 'light');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) { }
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
window.$docsify = {
|
||||||
|
name: '网易云音乐 API Enhanced',
|
||||||
|
repo: 'https://github.com/neteasecloudmusicapienhanced/api-enhanced',
|
||||||
|
coverpage: true,
|
||||||
|
homepage: 'https://cdn.jsdelivr.net/gh/NeteaseCloudMusicApiEnhanced/api-enhanced@main/public/docs/home.md',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="https://unpkg.com/docsify@4.11.3/lib/docsify.min.js"></script>
|
||||||
|
<script>
|
||||||
|
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||||
|
navigator.serviceWorker.register('sw.js')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-BPRGR23JEG"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() { dataLayer.push(arguments); }
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'G-BPRGR23JEG');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</html>
|
||||||
Vendored
-1833
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
|||||||
## 环境
|
|
||||||
- 系统/平台: <你的系统和平台>
|
|
||||||
|
|
||||||
- nodejs 版本: <你的 NodeJS 版本号>
|
|
||||||
|
|
||||||
- API版本:<运行的云音乐 API 的版本号, 对应 package.json 里面的 version>
|
|
||||||
|
|
||||||
## 出现问题
|
|
||||||
<出现的问题>
|
|
||||||
|
|
||||||
## 重现步骤
|
|
||||||
<重现步骤>
|
|
||||||
|
|
||||||
## 期待效果
|
|
||||||
<现在的效果,期待的效果>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
>先看文档有没有相关说明,调用前须知必看
|
|
||||||
|
|
||||||
>先在 issues 搜一下是否有相似问题,没有再发,否则直接关闭
|
|
||||||
|
|
||||||
>不处理别人搭建的线上服务的问题,此项目不提供任何线上服务,请自行搭建
|
|
||||||
|
|
||||||
>重现步骤尽量详细,不能含糊不清,包含请求地址和对应参数以及操作过程描述,不是每个人都喜欢猜别人遇到了什么问题和找参数一个个试,也比较浪费时间
|
|
||||||
|
|
||||||
>如果不是提建议,提 issues 如果不照着模版来将不会优先处理或直接关闭
|
|
||||||
|
|
||||||
>460 cheating 的问题把 `util/request.js` 里面的 `headers['X-Real-IP']` 的注释取消掉就好
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const tmpPath = require('os').tmpdir()
|
|
||||||
const { cookieToJson } = require('./util')
|
|
||||||
|
|
||||||
if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) {
|
|
||||||
fs.writeFileSync(path.resolve(tmpPath, 'anonymous_token'), '', 'utf-8')
|
|
||||||
}
|
|
||||||
|
|
||||||
let firstRun = true
|
|
||||||
/** @type {Record<string, any>} */
|
|
||||||
let obj = {}
|
|
||||||
fs.readdirSync(path.join(__dirname, 'module'))
|
|
||||||
.reverse()
|
|
||||||
.forEach((file) => {
|
|
||||||
if (!file.endsWith('.js')) return
|
|
||||||
let fileModule = require(path.join(__dirname, 'module', file))
|
|
||||||
let fn = file.split('.').shift() || ''
|
|
||||||
obj[fn] = function (data = {}) {
|
|
||||||
if (typeof data.cookie === 'string') {
|
|
||||||
data.cookie = cookieToJson(data.cookie)
|
|
||||||
}
|
|
||||||
return fileModule(
|
|
||||||
{
|
|
||||||
...data,
|
|
||||||
cookie: data.cookie ? data.cookie : {},
|
|
||||||
},
|
|
||||||
async (...args) => {
|
|
||||||
if (firstRun) {
|
|
||||||
firstRun = false
|
|
||||||
const generateConfig = require('./generateConfig')
|
|
||||||
await generateConfig()
|
|
||||||
}
|
|
||||||
// 待优化
|
|
||||||
const request = require('./util/request')
|
|
||||||
|
|
||||||
return request(...args)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Record<string, any> & import("./server")}
|
|
||||||
*/
|
|
||||||
module.exports = {
|
|
||||||
...require('./server'),
|
|
||||||
...obj,
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const assert = require('assert')
|
|
||||||
const main = require('./main')
|
|
||||||
|
|
||||||
describe('methods in server.js', () => {
|
|
||||||
it('has serveNcmApi', () => {
|
|
||||||
assert.strictEqual(typeof main.serveNcmApi, 'function')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('has getModulesDefinitions', () => {
|
|
||||||
assert.strictEqual(typeof main.getModulesDefinitions, 'function')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('methods in module', () => {
|
|
||||||
it('has activate_init_profile', () => {
|
|
||||||
assert.strictEqual(typeof main.activate_init_profile, 'function')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// 初始化名字
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
nickname: query.nickname,
|
|
||||||
}
|
|
||||||
return request(`/api/activate/initProfile`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
// 私人 DJ
|
|
||||||
|
|
||||||
// 实际请求参数如下, 部分内容省略, 敏感信息已进行混淆
|
|
||||||
// 可按需修改此 API 的代码
|
|
||||||
/* {"extInfo":"{\"lastRequestTimestamp\":1692358373509,\"lbsInfoList\":[{\"lat\":40.23076381,\"lon\":129.07545186,\"time\":1692358543},{\"lat\":40.23076381,\"lon\":129.07545186,\"time\":1692055283}],\"listenedTs\":false,\"noAidjToAidj\":true}","header":"{}"} */
|
|
||||||
|
|
||||||
const logger = require('../util/logger.js')
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
var extInfo = {}
|
|
||||||
if (query.latitude != undefined) {
|
|
||||||
extInfo.lbsInfoList = [
|
|
||||||
{
|
|
||||||
lat: query.latitude,
|
|
||||||
lon: query.longitude,
|
|
||||||
time: Date.parse(new Date()) / 1000,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
extInfo.noAidjToAidj = false
|
|
||||||
extInfo.lastRequestTimestamp = new Date().getTime()
|
|
||||||
extInfo.listenedTs = false
|
|
||||||
const data = {
|
|
||||||
extInfo: JSON.stringify(extInfo),
|
|
||||||
}
|
|
||||||
// logger.info(data)
|
|
||||||
return request(`/api/aidj/content/rcmd/info`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// 专辑内容
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
return request(`/api/v1/album/${query.id}`, {}, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// 数字专辑详情
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/vipmall/albumproduct/detail`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// 专辑动态信息
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/album/detail/dynamic`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 数字专辑-新碟上架
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 30,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
|
|
||||||
type: query.type,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/vipmall/albumproduct/list`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// 数字专辑-语种风格馆
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 10,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
area: query.area || 'Z_H', //Z_H:华语,E_A:欧美,KR:韩国,JP:日本
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/vipmall/appalbum/album/style`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 全部新碟
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 30,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
|
|
||||||
}
|
|
||||||
return request(`/api/album/new`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// 最新专辑
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
return request(`/api/discovery/newAlbum`, {}, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// 获取专辑歌曲的音质
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(`/api/album/privilege`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// 数字专辑&数字单曲-榜单
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
let data = {
|
|
||||||
albumType: query.albumType || 0, //0为数字专辑,1为数字单曲
|
|
||||||
}
|
|
||||||
const type = query.type || 'daily' // daily,week,year,total
|
|
||||||
if (type === 'year') {
|
|
||||||
data = {
|
|
||||||
...data,
|
|
||||||
year: query.year,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/feealbum/songsaleboard/${type}/type`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// 收藏/取消收藏专辑
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.t = query.t == 1 ? 'sub' : 'unsub'
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(`/api/album/${query.t}`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 已收藏专辑列表
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 25,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
}
|
|
||||||
return request(`/api/album/sublist`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
const { cookieToJson } = require('../util/index')
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const uri = query.uri
|
|
||||||
let data = {}
|
|
||||||
try {
|
|
||||||
data =
|
|
||||||
typeof query.data === 'string' ? JSON.parse(query.data) : query.data || {}
|
|
||||||
if (typeof data.cookie === 'string') {
|
|
||||||
data.cookie = cookieToJson(data.cookie)
|
|
||||||
query.cookie = data.cookie
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
data = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const crypto = query.crypto || ''
|
|
||||||
|
|
||||||
const res = request(uri, data, createOption(query, crypto))
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// 歌手专辑列表
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 30,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/artist/albums/${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// 歌手介绍
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(`/api/artist/introduction`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
return request(
|
|
||||||
`/api/artist/head/info/get`,
|
|
||||||
{
|
|
||||||
id: query.id,
|
|
||||||
},
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// 歌手动态信息
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(`/api/artist/detail/dynamic`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 歌手粉丝
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
}
|
|
||||||
return request(`/api/artist/fans/get`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// 歌手粉丝数量
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/artist/follow/count/get`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// 歌手分类
|
|
||||||
|
|
||||||
/*
|
|
||||||
type 取值
|
|
||||||
1:男歌手
|
|
||||||
2:女歌手
|
|
||||||
3:乐队
|
|
||||||
|
|
||||||
area 取值
|
|
||||||
-1:全部
|
|
||||||
7华语
|
|
||||||
96欧美
|
|
||||||
8:日本
|
|
||||||
16韩国
|
|
||||||
0:其他
|
|
||||||
|
|
||||||
initial 取值 a-z/A-Z
|
|
||||||
*/
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
initial: isNaN(query.initial)
|
|
||||||
? (query.initial || '').toUpperCase().charCodeAt() || undefined
|
|
||||||
: query.initial,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
limit: query.limit || 30,
|
|
||||||
total: true,
|
|
||||||
type: query.type || '1',
|
|
||||||
area: query.area,
|
|
||||||
}
|
|
||||||
return request(`/api/v1/artist/list`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// 歌手相关MV
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
artistId: query.id,
|
|
||||||
limit: query.limit,
|
|
||||||
offset: query.offset,
|
|
||||||
total: true,
|
|
||||||
}
|
|
||||||
return request(`/api/artist/mvs`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 20,
|
|
||||||
startTimestamp: query.before || Date.now(),
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/sub/artist/new/works/mv/list`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 20,
|
|
||||||
startTimestamp: query.before || Date.now(),
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/sub/artist/new/works/song/list`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
private_cloud: 'true',
|
|
||||||
work_type: 1,
|
|
||||||
order: query.order || 'hot', //hot,time
|
|
||||||
offset: query.offset || 0,
|
|
||||||
limit: query.limit || 100,
|
|
||||||
}
|
|
||||||
return request(`/api/v1/artist/songs`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 收藏与取消收藏歌手
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.t = query.t == 1 ? 'sub' : 'unsub'
|
|
||||||
const data = {
|
|
||||||
artistId: query.id,
|
|
||||||
artistIds: '[' + query.id + ']',
|
|
||||||
}
|
|
||||||
return request(`/api/artist/${query.t}`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 关注歌手列表
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 25,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
}
|
|
||||||
return request(`/api/artist/sublist`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// 歌手热门 50 首歌曲
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
id: query.id,
|
|
||||||
}
|
|
||||||
return request(`/api/artist/top/song`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// 歌手相关视频
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
artistId: query.id,
|
|
||||||
page: JSON.stringify({
|
|
||||||
size: query.size || 10,
|
|
||||||
cursor: query.cursor || 0,
|
|
||||||
}),
|
|
||||||
tab: 0,
|
|
||||||
order: query.order || 0,
|
|
||||||
}
|
|
||||||
return request(`/api/mlog/artist/video`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// 歌手单曲
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
return request(`/api/v1/artist/${query.id}`, {}, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
const { default: axios } = require('axios')
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = async (query, request) => {
|
|
||||||
const res = await axios({
|
|
||||||
method: 'get',
|
|
||||||
url: `https://interface.music.163.com/api/music/audio/match?sessionId=0123456789abcdef&algorithmCode=shazam_v2&duration=${
|
|
||||||
query.duration
|
|
||||||
}&rawdata=${encodeURIComponent(query.audioFP)}×=1&decrypt=1`,
|
|
||||||
data: null,
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
body: {
|
|
||||||
code: 200,
|
|
||||||
data: res.data.data,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
const uploadPlugin = require('../plugins/upload')
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = async (query, request) => {
|
|
||||||
const uploadInfo = await uploadPlugin(query, request)
|
|
||||||
const res = await request(
|
|
||||||
`/api/user/avatar/upload/v1`,
|
|
||||||
{
|
|
||||||
imgid: uploadInfo.imgId,
|
|
||||||
},
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
body: {
|
|
||||||
code: 200,
|
|
||||||
data: {
|
|
||||||
...uploadInfo,
|
|
||||||
...res.body,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 首页轮播图
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const type =
|
|
||||||
{
|
|
||||||
0: 'pc',
|
|
||||||
1: 'android',
|
|
||||||
2: 'iphone',
|
|
||||||
3: 'ipad',
|
|
||||||
}[query.type || 0] || 'pc'
|
|
||||||
return request(
|
|
||||||
`/api/v2/banner/get`,
|
|
||||||
{ clientType: type },
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// 批量请求接口
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {}
|
|
||||||
Object.keys(query).forEach((i) => {
|
|
||||||
if (/^\/api\//.test(i)) {
|
|
||||||
data[i] = query[i]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return request(`/api/batch`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 广播电台 - 分类/地区信息
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {}
|
|
||||||
return request(
|
|
||||||
`/api/voice/broadcast/category/region/get`,
|
|
||||||
data,
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// 广播电台 - 我的收藏
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
contentType: 'BROADCAST',
|
|
||||||
limit: query.limit || '99999',
|
|
||||||
timeReverseOrder: 'true',
|
|
||||||
startDate: '4762584922000',
|
|
||||||
}
|
|
||||||
return request(`/api/content/channel/collect/list`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// 广播电台 - 电台信息
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
channelId: query.id,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/voice/broadcast/channel/currentinfo`,
|
|
||||||
data,
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// 广播电台 - 全部电台
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
categoryId: query.categoryId || '0',
|
|
||||||
regionId: query.regionId || '0',
|
|
||||||
limit: query.limit || '20',
|
|
||||||
lastId: query.lastId || '0',
|
|
||||||
score: query.score || '-1',
|
|
||||||
}
|
|
||||||
return request(`/api/voice/broadcast/channel/list`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// 广播电台 - 收藏/取消收藏电台
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.t = query.t == 1 ? 'false' : 'true'
|
|
||||||
const data = {
|
|
||||||
contentType: 'BROADCAST',
|
|
||||||
contentId: query.id,
|
|
||||||
cancelCollect: query.t,
|
|
||||||
}
|
|
||||||
return request(`/api/content/interact/collect`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
startTime: query.startTime || Date.now(),
|
|
||||||
endTime: query.endTime || Date.now(),
|
|
||||||
}
|
|
||||||
return request(`/api/mcalendar/detail`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// 发送验证码
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
ctcode: query.ctcode || '86',
|
|
||||||
cellphone: query.phone,
|
|
||||||
}
|
|
||||||
return request(`/api/sms/captcha/sent`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// 校验验证码
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
ctcode: query.ctcode || '86',
|
|
||||||
cellphone: query.phone,
|
|
||||||
captcha: query.captcha,
|
|
||||||
}
|
|
||||||
return request(`/api/sms/captcha/verify`, data, createOption(query, 'weapi'))
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// 检测手机号码是否已注册
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
cellphone: query.phone,
|
|
||||||
countrycode: query.countrycode,
|
|
||||||
}
|
|
||||||
return request(`/api/cellphone/existence/check`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// 歌曲可用性
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
ids: '[' + parseInt(query.id) + ']',
|
|
||||||
br: parseInt(query.br || 999000),
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/song/enhance/player/url`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
).then((response) => {
|
|
||||||
let playable = false
|
|
||||||
if (response.body.code == 200) {
|
|
||||||
if (response.body.data[0].code == 200) {
|
|
||||||
playable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (playable) {
|
|
||||||
response.body = { code: 200, success: true, message: 'ok' }
|
|
||||||
return response
|
|
||||||
} else {
|
|
||||||
// response.status = 404
|
|
||||||
response.body = { code: 200, success: false, message: '亲爱的,暂无版权' }
|
|
||||||
return response
|
|
||||||
// return Promise.reject(response)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
-146
@@ -1,146 +0,0 @@
|
|||||||
const mm = require('music-metadata')
|
|
||||||
const uploadPlugin = require('../plugins/songUpload')
|
|
||||||
const md5 = require('md5')
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
const logger = require('../util/logger.js')
|
|
||||||
module.exports = async (query, request) => {
|
|
||||||
let ext = 'mp3'
|
|
||||||
// if (query.songFile.name.indexOf('flac') > -1) {
|
|
||||||
// ext = 'flac'
|
|
||||||
// }
|
|
||||||
if (query.songFile.name.includes('.')) {
|
|
||||||
ext = query.songFile.name.split('.').pop()
|
|
||||||
}
|
|
||||||
query.songFile.name = Buffer.from(query.songFile.name, 'latin1').toString(
|
|
||||||
'utf-8',
|
|
||||||
)
|
|
||||||
const filename = query.songFile.name
|
|
||||||
.replace('.' + ext, '')
|
|
||||||
.replace(/\s/g, '')
|
|
||||||
.replace(/\./g, '_')
|
|
||||||
const bitrate = 999000
|
|
||||||
if (!query.songFile) {
|
|
||||||
return Promise.reject({
|
|
||||||
status: 500,
|
|
||||||
body: {
|
|
||||||
msg: '请上传音乐文件',
|
|
||||||
code: 500,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (!query.songFile.md5) {
|
|
||||||
// 命令行上传没有md5和size信息,需要填充
|
|
||||||
query.songFile.md5 = md5(query.songFile.data)
|
|
||||||
query.songFile.size = query.songFile.data.byteLength
|
|
||||||
}
|
|
||||||
const res = await request(
|
|
||||||
`/api/cloud/upload/check`,
|
|
||||||
{
|
|
||||||
bitrate: String(bitrate),
|
|
||||||
ext: '',
|
|
||||||
length: query.songFile.size,
|
|
||||||
md5: query.songFile.md5,
|
|
||||||
songId: '0',
|
|
||||||
version: 1,
|
|
||||||
},
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
let artist = ''
|
|
||||||
let album = ''
|
|
||||||
let songName = ''
|
|
||||||
try {
|
|
||||||
const metadata = await mm.parseBuffer(
|
|
||||||
query.songFile.data,
|
|
||||||
query.songFile.mimetype,
|
|
||||||
)
|
|
||||||
const info = metadata.common
|
|
||||||
|
|
||||||
if (info.title) {
|
|
||||||
songName = info.title
|
|
||||||
}
|
|
||||||
if (info.album) {
|
|
||||||
album = info.album
|
|
||||||
}
|
|
||||||
if (info.artist) {
|
|
||||||
artist = info.artist
|
|
||||||
}
|
|
||||||
// if (metadata.native.ID3v1) {
|
|
||||||
// metadata.native.ID3v1.forEach((item) => {
|
|
||||||
// // logger.info(item.id, item.value)
|
|
||||||
// if (item.id === 'title') {
|
|
||||||
// songName = item.value
|
|
||||||
// }
|
|
||||||
// if (item.id === 'artist') {
|
|
||||||
// artist = item.value
|
|
||||||
// }
|
|
||||||
// if (item.id === 'album') {
|
|
||||||
// album = item.value
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// // logger.info({
|
|
||||||
// // songName,
|
|
||||||
// // album,
|
|
||||||
// // songName,
|
|
||||||
// // })
|
|
||||||
// }
|
|
||||||
// logger.info({
|
|
||||||
// songName,
|
|
||||||
// album,
|
|
||||||
// songName,
|
|
||||||
// })
|
|
||||||
} catch (error) {
|
|
||||||
logger.info(error)
|
|
||||||
}
|
|
||||||
const tokenRes = await request(
|
|
||||||
`/api/nos/token/alloc`,
|
|
||||||
{
|
|
||||||
bucket: '',
|
|
||||||
ext: ext,
|
|
||||||
filename: filename,
|
|
||||||
local: false,
|
|
||||||
nos_product: 3,
|
|
||||||
type: 'audio',
|
|
||||||
md5: query.songFile.md5,
|
|
||||||
},
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
|
|
||||||
if (res.body.needUpload) {
|
|
||||||
const uploadInfo = await uploadPlugin(query, request)
|
|
||||||
// logger.info('uploadInfo', uploadInfo.body.result.resourceId)
|
|
||||||
}
|
|
||||||
// logger.info(tokenRes.body.result)
|
|
||||||
const res2 = await request(
|
|
||||||
`/api/upload/cloud/info/v2`,
|
|
||||||
{
|
|
||||||
md5: query.songFile.md5,
|
|
||||||
songid: res.body.songId,
|
|
||||||
filename: query.songFile.name,
|
|
||||||
song: songName || filename,
|
|
||||||
album: album || '未知专辑',
|
|
||||||
artist: artist || '未知艺术家',
|
|
||||||
bitrate: String(bitrate),
|
|
||||||
resourceId: tokenRes.body.result.resourceId,
|
|
||||||
},
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
// logger.info({ res2, privateCloud: res2.body.privateCloud })
|
|
||||||
// logger.info(res.body.songId, 'songid')
|
|
||||||
const res3 = await request(
|
|
||||||
`/api/cloud/pub/v2`,
|
|
||||||
{
|
|
||||||
songid: res2.body.songId,
|
|
||||||
},
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
// logger.info({ res3 })
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
body: {
|
|
||||||
...res.body,
|
|
||||||
...res3.body,
|
|
||||||
// ...uploadInfo,
|
|
||||||
},
|
|
||||||
cookie: res.cookie,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
// 云盘导入歌曲
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = async (query, request) => {
|
|
||||||
query.id = query.id || -2
|
|
||||||
query.artist = query.artist || '未知'
|
|
||||||
query.album = query.album || '未知'
|
|
||||||
const checkData = {
|
|
||||||
uploadType: 0,
|
|
||||||
songs: JSON.stringify([
|
|
||||||
{
|
|
||||||
md5: query.md5,
|
|
||||||
songId: query.id,
|
|
||||||
bitrate: query.bitrate,
|
|
||||||
fileSize: query.fileSize,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
}
|
|
||||||
const res = await request(
|
|
||||||
`/api/cloud/upload/check/v2`,
|
|
||||||
checkData,
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
//res.body.data[0].upload 0:文件可导入,1:文件已在云盘,2:不能导入
|
|
||||||
//只能用song决定云盘文件名,且上传后的文件名后缀固定为mp3
|
|
||||||
const importData = {
|
|
||||||
uploadType: 0,
|
|
||||||
songs: JSON.stringify([
|
|
||||||
{
|
|
||||||
songId: res.body.data[0].songId,
|
|
||||||
bitrate: query.bitrate,
|
|
||||||
song: query.song,
|
|
||||||
artist: query.artist,
|
|
||||||
album: query.album,
|
|
||||||
fileName: query.song + '.' + query.fileType,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
}
|
|
||||||
return request(`/api/cloud/user/song/import`, importData, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
userId: query.uid,
|
|
||||||
songId: query.sid,
|
|
||||||
adjustSongId: query.asid,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/cloud/user/song/match`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// 搜索
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
s: query.keywords,
|
|
||||||
type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
|
|
||||||
limit: query.limit || 30,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
total: true,
|
|
||||||
}
|
|
||||||
return request(`/api/cloudsearch/pc`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
const { resourceTypeMap } = require('../util/config.json')
|
|
||||||
// 发送与删除评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.t = {
|
|
||||||
1: 'add',
|
|
||||||
0: 'delete',
|
|
||||||
2: 'reply',
|
|
||||||
}[query.t]
|
|
||||||
query.type = resourceTypeMap[query.type]
|
|
||||||
const data = {
|
|
||||||
threadId: query.type + query.id,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.type == 'A_EV_2_') {
|
|
||||||
data.threadId = query.threadId
|
|
||||||
}
|
|
||||||
if (query.t == 'add') data.content = query.content
|
|
||||||
else if (query.t == 'delete') data.commentId = query.commentId
|
|
||||||
else if (query.t == 'reply') {
|
|
||||||
data.commentId = query.commentId
|
|
||||||
data.content = query.content
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/resource/comments/${query.t}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 专辑评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/R_AL_3_${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 电台评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/A_DJ_1_${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// 获取动态评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/${query.threadId}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
const { resourceTypeMap } = require('../util/config.json')
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.type = resourceTypeMap[query.type]
|
|
||||||
const data = {
|
|
||||||
parentCommentId: query.parentCommentId,
|
|
||||||
threadId: query.type + query.id,
|
|
||||||
time: query.time || -1,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/resource/comment/floor/get`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const { resourceTypeMap } = require('../util/config.json')
|
|
||||||
// 热门评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.type = resourceTypeMap[query.type]
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/hotcomments/${query.type}${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
const { resourceTypeMap } = require('../util/config.json')
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.type = resourceTypeMap[query.type || 0]
|
|
||||||
const threadId = query.type + query.sid
|
|
||||||
const data = {
|
|
||||||
targetUserId: query.uid,
|
|
||||||
commentId: query.cid,
|
|
||||||
cursor: query.cursor || '-1',
|
|
||||||
threadId: threadId,
|
|
||||||
pageNo: query.page || 1,
|
|
||||||
idCursor: query.idCursor || -1,
|
|
||||||
pageSize: query.pageSize || 100,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v2/resource/comments/hug/list`,
|
|
||||||
data,
|
|
||||||
createOption(query),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
const { resourceTypeMap } = require('../util/config.json')
|
|
||||||
// 点赞与取消点赞评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.t = query.t == 1 ? 'like' : 'unlike'
|
|
||||||
query.type = resourceTypeMap[query.type]
|
|
||||||
const data = {
|
|
||||||
threadId: query.type + query.id,
|
|
||||||
commentId: query.cid,
|
|
||||||
}
|
|
||||||
if (query.type == 'A_EV_2_') {
|
|
||||||
data.threadId = query.threadId
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/comment/${query.t}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 歌曲评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/R_SO_4_${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// MV评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/R_MV_5_${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
const { resourceTypeMap } = require('../util/config.json')
|
|
||||||
// 评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
query.type = resourceTypeMap[query.type]
|
|
||||||
const threadId = query.type + query.id
|
|
||||||
const pageSize = query.pageSize || 20
|
|
||||||
const pageNo = query.pageNo || 1
|
|
||||||
let sortType = Number(query.sortType) || 99
|
|
||||||
if (sortType === 1) {
|
|
||||||
sortType = 99
|
|
||||||
}
|
|
||||||
let cursor = ''
|
|
||||||
switch (sortType) {
|
|
||||||
case 99:
|
|
||||||
cursor = (pageNo - 1) * pageSize
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
cursor = 'normalHot#' + (pageNo - 1) * pageSize
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
cursor = query.cursor || '0'
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
const data = {
|
|
||||||
threadId: threadId,
|
|
||||||
pageNo,
|
|
||||||
showInner: query.showInner || true,
|
|
||||||
pageSize,
|
|
||||||
cursor: cursor,
|
|
||||||
sortType: sortType, //99:按推荐排序,2:按热度排序,3:按时间排序
|
|
||||||
}
|
|
||||||
return request(`/api/v2/resource/comments`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 歌单评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/A_PL_0_${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// 视频评论
|
|
||||||
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {
|
|
||||||
rid: query.id,
|
|
||||||
limit: query.limit || 20,
|
|
||||||
offset: query.offset || 0,
|
|
||||||
beforeTime: query.before || 0,
|
|
||||||
}
|
|
||||||
return request(
|
|
||||||
`/api/v1/resource/comments/R_VI_62_${query.id}`,
|
|
||||||
data,
|
|
||||||
createOption(query, 'weapi'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// 国家编码列表
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {}
|
|
||||||
return request(`/api/lbs/countries/v1`, data, createOption(query))
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// 获取达人用户信息
|
|
||||||
const createOption = require('../util/option.js')
|
|
||||||
module.exports = (query, request) => {
|
|
||||||
const data = {}
|
|
||||||
return request(`/api/user/creator/authinfo/get`, data, createOption(query))
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user