update: 播客声音上传接口和文档

This commit is contained in:
binaryify 2023-09-07 23:55:26 +08:00
parent 846b7e5fbc
commit dd2365bcb7
7 changed files with 210 additions and 105 deletions

View File

@ -1,4 +1,8 @@
# 更新日志
### 4.11.0 | 2023.09.07
- 新增 `播客搜索`,`播客上传声音`接口 #1789
### 4.10.2 | 2023.09.04
- 修复docker缺失文件问题 #1791

View File

@ -270,6 +270,8 @@
252. 曲风-歌手
253. 私信和通知接口
254. 回忆坐标
255. 播客搜索
256. 播客声音上传
## 安装
@ -4159,6 +4161,54 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**必选参数:** `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, 可离线访问

View File

@ -19,9 +19,8 @@ module.exports = async (query, request) => {
if (query.songFile.name.indexOf('flac') > -1) {
ext = 'flac'
}
const filename =
query.filename ||
query.songName ||
query.songFile.name
.replace('.' + ext, '')
.replace(/\s/g, '')
@ -102,19 +101,20 @@ module.exports = async (query, request) => {
voiceData: JSON.stringify([
{
name: filename,
autoPublish: true,
autoPublishText: '',
autoPublish: query.autoPublish == 1 ? true : false,
autoPublishText: query.autoPublishText || '',
description: query.description,
// 换成自己的
voiceListId: query.voiceListId,
coverImgId: query.coverImgId,
dfsId: docId,
categoryId: query.categoryId,
secondCategoryId: query.secondCategoryId,
composedSongs: [],
privacy: true,
publishTime: 0,
orderNo: 1,
composedSongs: query.composedSongs
? query.composedSongs.split(',')
: [],
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([
{
name: filename,
autoPublish: true,
autoPublishText: '',
autoPublish: query.autoPublish == 1 ? true : false,
autoPublishText: query.autoPublishText || '',
description: query.description,
// 换成自己的
voiceListId: query.voiceListId || 994681645,
voiceListId: query.voiceListId,
coverImgId: query.coverImgId,
dfsId: docId,
categoryId: query.categoryId,
secondCategoryId: query.secondCategoryId || 466050,
composedSongs: [],
privacy: true,
publishTime: 0,
orderNo: 1,
secondCategoryId: query.secondCategoryId,
composedSongs: query.composedSongs
? query.composedSongs.split(',')
: [],
privacy: query.privacy == 1 ? true : false,
publishTime: query.publishTime || 0,
orderNo: query.orderNo || 1,
},
]),
},

View File

@ -1,8 +1,9 @@
module.exports = (query, request) => {
const data = {
fee: '-1',
limit: '200',
podcastName: '',
limit: query.limit || '200',
offset: query.offset || '0',
podcastName: query.podcastName || '',
}
return request(
'POST',

View File

@ -1,6 +1,6 @@
{
"name": "NeteaseCloudMusicApi",
"version": "4.10.2",
"version": "4.11.0",
"description": "网易云音乐 NodeJS 版 API",
"scripts": {
"start": "node app.js",

View File

@ -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
View 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>