mirror of
https://gitlab.com/Binaryify/neteasecloudmusicapi.git
synced 2025-05-23 22:37:41 +08:00
update: 播客声音上传接口和文档
This commit is contained in:
parent
846b7e5fbc
commit
dd2365bcb7
@ -1,4 +1,8 @@
|
|||||||
# 更新日志
|
# 更新日志
|
||||||
|
### 4.11.0 | 2023.09.07
|
||||||
|
- 新增 `播客搜索`,`播客上传声音`接口 #1789
|
||||||
|
|
||||||
|
|
||||||
### 4.10.2 | 2023.09.04
|
### 4.10.2 | 2023.09.04
|
||||||
- 修复docker缺失文件问题 #1791
|
- 修复docker缺失文件问题 #1791
|
||||||
|
|
||||||
|
@ -270,6 +270,8 @@
|
|||||||
252. 曲风-歌手
|
252. 曲风-歌手
|
||||||
253. 私信和通知接口
|
253. 私信和通知接口
|
||||||
254. 回忆坐标
|
254. 回忆坐标
|
||||||
|
255. 播客搜索
|
||||||
|
256. 播客声音上传
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
@ -4159,6 +4161,54 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
|
|||||||
|
|
||||||
**必选参数:** `id` : 歌曲 ID
|
**必选参数:** `id` : 歌曲 ID
|
||||||
|
|
||||||
|
### 播客列表
|
||||||
|
|
||||||
|
说明: 可以获取播客列表
|
||||||
|
|
||||||
|
**接口地址:** `/voicelist/search`
|
||||||
|
|
||||||
|
**可选参数:**
|
||||||
|
|
||||||
|
`limit`: 取出歌单数量 , 默认为 200
|
||||||
|
|
||||||
|
`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*200, 其中 200 为 limit 的值
|
||||||
|
|
||||||
|
`podcastName`: 播客名称
|
||||||
|
|
||||||
|
### 播客上传声音
|
||||||
|
说明: 可以上传声音到播客,例子在 `/public/voice_upload.html` 访问地址: <a href="/voice_upload.html" target="_blank">/voice_upload.html</a>
|
||||||
|
|
||||||
|
**接口地址:** `/voice/upload`
|
||||||
|
|
||||||
|
**必选参数:**
|
||||||
|
`voiceListId`: 播客 id
|
||||||
|
|
||||||
|
`coverImgId`: 播客封面
|
||||||
|
|
||||||
|
`categoryId`: 分类id
|
||||||
|
|
||||||
|
`secondCategoryId`:次级分类id
|
||||||
|
|
||||||
|
`description`: 声音介绍
|
||||||
|
|
||||||
|
|
||||||
|
**可选参数:**
|
||||||
|
`songName`: 声音名称
|
||||||
|
|
||||||
|
`privacy`: 设为隐私声音,播客如果是隐私博客,则必须设为1
|
||||||
|
|
||||||
|
`publishTime`:默认立即发布,定时发布的话需传入时间戳
|
||||||
|
|
||||||
|
`autoPublish`: 是否发布动态,是则传入1
|
||||||
|
|
||||||
|
`autoPublishText`: 动态文案
|
||||||
|
|
||||||
|
`orderNo`: 排序,默认为1
|
||||||
|
|
||||||
|
`composedSongs`: 包含歌曲(歌曲id),多个用逗号隔开
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 离线访问此文档
|
## 离线访问此文档
|
||||||
|
|
||||||
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
||||||
|
@ -19,9 +19,8 @@ module.exports = async (query, request) => {
|
|||||||
if (query.songFile.name.indexOf('flac') > -1) {
|
if (query.songFile.name.indexOf('flac') > -1) {
|
||||||
ext = 'flac'
|
ext = 'flac'
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename =
|
const filename =
|
||||||
query.filename ||
|
query.songName ||
|
||||||
query.songFile.name
|
query.songFile.name
|
||||||
.replace('.' + ext, '')
|
.replace('.' + ext, '')
|
||||||
.replace(/\s/g, '')
|
.replace(/\s/g, '')
|
||||||
@ -102,19 +101,20 @@ module.exports = async (query, request) => {
|
|||||||
voiceData: JSON.stringify([
|
voiceData: JSON.stringify([
|
||||||
{
|
{
|
||||||
name: filename,
|
name: filename,
|
||||||
autoPublish: true,
|
autoPublish: query.autoPublish == 1 ? true : false,
|
||||||
autoPublishText: '',
|
autoPublishText: query.autoPublishText || '',
|
||||||
description: query.description,
|
description: query.description,
|
||||||
// 换成自己的
|
|
||||||
voiceListId: query.voiceListId,
|
voiceListId: query.voiceListId,
|
||||||
coverImgId: query.coverImgId,
|
coverImgId: query.coverImgId,
|
||||||
dfsId: docId,
|
dfsId: docId,
|
||||||
categoryId: query.categoryId,
|
categoryId: query.categoryId,
|
||||||
secondCategoryId: query.secondCategoryId,
|
secondCategoryId: query.secondCategoryId,
|
||||||
composedSongs: [],
|
composedSongs: query.composedSongs
|
||||||
privacy: true,
|
? query.composedSongs.split(',')
|
||||||
publishTime: 0,
|
: [],
|
||||||
orderNo: 1,
|
privacy: query.privacy == 1 ? true : false,
|
||||||
|
publishTime: query.publishTime || 0,
|
||||||
|
orderNo: query.orderNo || 1,
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
@ -135,19 +135,20 @@ module.exports = async (query, request) => {
|
|||||||
voiceData: JSON.stringify([
|
voiceData: JSON.stringify([
|
||||||
{
|
{
|
||||||
name: filename,
|
name: filename,
|
||||||
autoPublish: true,
|
autoPublish: query.autoPublish == 1 ? true : false,
|
||||||
autoPublishText: '',
|
autoPublishText: query.autoPublishText || '',
|
||||||
description: query.description,
|
description: query.description,
|
||||||
// 换成自己的
|
voiceListId: query.voiceListId,
|
||||||
voiceListId: query.voiceListId || 994681645,
|
|
||||||
coverImgId: query.coverImgId,
|
coverImgId: query.coverImgId,
|
||||||
dfsId: docId,
|
dfsId: docId,
|
||||||
categoryId: query.categoryId,
|
categoryId: query.categoryId,
|
||||||
secondCategoryId: query.secondCategoryId || 466050,
|
secondCategoryId: query.secondCategoryId,
|
||||||
composedSongs: [],
|
composedSongs: query.composedSongs
|
||||||
privacy: true,
|
? query.composedSongs.split(',')
|
||||||
publishTime: 0,
|
: [],
|
||||||
orderNo: 1,
|
privacy: query.privacy == 1 ? true : false,
|
||||||
|
publishTime: query.publishTime || 0,
|
||||||
|
orderNo: query.orderNo || 1,
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
module.exports = (query, request) => {
|
module.exports = (query, request) => {
|
||||||
const data = {
|
const data = {
|
||||||
fee: '-1',
|
fee: '-1',
|
||||||
limit: '200',
|
limit: query.limit || '200',
|
||||||
podcastName: '',
|
offset: query.offset || '0',
|
||||||
|
podcastName: query.podcastName || '',
|
||||||
}
|
}
|
||||||
return request(
|
return request(
|
||||||
'POST',
|
'POST',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "NeteaseCloudMusicApi",
|
"name": "NeteaseCloudMusicApi",
|
||||||
"version": "4.10.2",
|
"version": "4.11.0",
|
||||||
"description": "网易云音乐 NodeJS 版 API",
|
"description": "网易云音乐 NodeJS 版 API",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node app.js",
|
"start": "node app.js",
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>播客上传</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<input id="file" type="file" multiple />
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/axios@0.26.1/dist/axios.min.js"></script>
|
|
||||||
<script>
|
|
||||||
const phone = '' // 这里填手机号
|
|
||||||
const password = '' // 这里填密码
|
|
||||||
const fileUpdateTime = {}
|
|
||||||
let fileLength = 0
|
|
||||||
let cookieToken = ''
|
|
||||||
if (!phone || !password) {
|
|
||||||
const msg = '请设置你的手机号码和密码'
|
|
||||||
alert(msg)
|
|
||||||
throw new Error(msg)
|
|
||||||
}
|
|
||||||
login()
|
|
||||||
main()
|
|
||||||
async function login() {
|
|
||||||
const res = await axios({
|
|
||||||
url: `/login/cellphone?phone=${phone}&password=${encodeURIComponent(
|
|
||||||
password,
|
|
||||||
)}`,
|
|
||||||
withCredentials: true, //跨域的话必须设置
|
|
||||||
})
|
|
||||||
cookieToken = res.data.cookie
|
|
||||||
}
|
|
||||||
function main() {
|
|
||||||
document
|
|
||||||
.querySelector('input[type="file"]')
|
|
||||||
.addEventListener('change', function (e) {
|
|
||||||
console.log(this.files)
|
|
||||||
let currentIndx = 0
|
|
||||||
fileLength = this.files.length
|
|
||||||
for (const item of this.files) {
|
|
||||||
currentIndx += 1
|
|
||||||
upload(item, currentIndx)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function upload(file, currentIndx) {
|
|
||||||
var formData = new FormData()
|
|
||||||
formData.append('songFile', file)
|
|
||||||
axios({
|
|
||||||
method: 'post',
|
|
||||||
url: `/audio/upload?time=${Date.now()}&cookie=${cookieToken}`,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
},
|
|
||||||
data: formData,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(`${file.name} 上传成功`)
|
|
||||||
if (currentIndx >= fileLength) {
|
|
||||||
console.log('上传完毕')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(async (err) => {
|
|
||||||
console.log(err)
|
|
||||||
console.log(fileUpdateTime)
|
|
||||||
fileUpdateTime[file.name]
|
|
||||||
? (fileUpdateTime[file.name] += 1)
|
|
||||||
: (fileUpdateTime[file.name] = 1)
|
|
||||||
if (fileUpdateTime[file.name] >= 4) {
|
|
||||||
console.error(`上传失败:${file.name}`)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
console.error(`${file.name} 失败 ${fileUpdateTime[file.name]} 次`)
|
|
||||||
}
|
|
||||||
// await login()
|
|
||||||
upload(file, currentIndx)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
133
public/voice_upload.html
Normal file
133
public/voice_upload.html
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>播客上传声音</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<ul>
|
||||||
|
<li v-for="(item,index) in voicelist" @click="currentVoiceIndex=index"
|
||||||
|
:class="{active:currentVoiceIndex===index}">
|
||||||
|
<img :src="item.coverUrl" style="width:50px;width:50px;" />
|
||||||
|
{{item.voiceListName}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<input v-model="songName" placeholder="请输入声音名称" />
|
||||||
|
<input v-model="description" placeholder="请输入介绍" />
|
||||||
|
<input type="file" name="songFile" />
|
||||||
|
<button @click="submit">上传</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/axios@0.26.1/dist/axios.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
|
||||||
|
<script>
|
||||||
|
Vue.createApp({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
songName: '',
|
||||||
|
description: '',
|
||||||
|
voicelist: [],
|
||||||
|
cookieToken: '',
|
||||||
|
currentVoiceIndex: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentVoice() {
|
||||||
|
// {
|
||||||
|
// voiceListId: '',
|
||||||
|
// coverImgId: '',
|
||||||
|
// categoryId: '',
|
||||||
|
// secondCategoryId: '',
|
||||||
|
// }
|
||||||
|
return this.voicelist[this.currentVoiceIndex]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
console.log('submit')
|
||||||
|
const file = document.querySelector('input[type=file]').files[0]
|
||||||
|
this.upload(file)
|
||||||
|
},
|
||||||
|
async login() {
|
||||||
|
const phone = '' // 这里填手机号
|
||||||
|
const password = '' // 这里填密码
|
||||||
|
const fileUpdateTime = {}
|
||||||
|
let fileLength = 0
|
||||||
|
if (!phone || !password) {
|
||||||
|
const msg = '请设置你的手机号码和密码'
|
||||||
|
alert(msg)
|
||||||
|
throw new Error(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await axios({
|
||||||
|
url: `/login/cellphone`,
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
phone,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
this.cookieToken = res.data.cookie
|
||||||
|
},
|
||||||
|
async getData() {
|
||||||
|
await this.login()
|
||||||
|
const res = await axios({
|
||||||
|
url: `/voicelist/search?cookie=${this.cookieToken}`,
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(res.data.data)
|
||||||
|
this.voicelist = res.data.data.list
|
||||||
|
},
|
||||||
|
upload(file) {
|
||||||
|
var formData = new FormData()
|
||||||
|
formData.append('songFile', file)
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: `/voice/upload?time=${Date.now()}&cookie=${
|
||||||
|
this.cookieToken
|
||||||
|
}&songName=${this.songName}&voiceListId=${
|
||||||
|
this.currentVoice.voiceListId
|
||||||
|
}&categoryId=${this.currentVoice.categoryId}&coverImgId=${
|
||||||
|
this.currentVoice.coverImgId
|
||||||
|
}&secondCategoryId=${this.currentVoice.secondCategoryId}&description=${
|
||||||
|
this.description
|
||||||
|
}&privacy=1`,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
},
|
||||||
|
data: formData,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
alert(`${file.name} 上传成功`)
|
||||||
|
if (currentIndx >= fileLength) {
|
||||||
|
console.log('上传完毕')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(async (err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).mount('#app')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
ul li {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li.active {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user