You've already forked lx-music-desktop
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9858170e61 | ||
|
|
16711e33e8 | ||
|
|
f534e11acb | ||
|
|
2ff0f4b102 | ||
|
|
5b2a44e3bd | ||
|
|
0b06206d34 | ||
|
|
cb93dfa218 | ||
|
|
c92517960e | ||
|
|
3a615a4a87 | ||
|
|
78d2541c14 | ||
|
|
b8d07b365b | ||
|
|
2d5848db94 | ||
|
|
d4c88edb8b |
37
CHANGELOG.md
37
CHANGELOG.md
@@ -6,6 +6,43 @@ Project versioning adheres to [Semantic Versioning](http://semver.org/).
|
||||
Commit convention is based on [Conventional Commits](http://conventionalcommits.org).
|
||||
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||
|
||||
## [0.2.2](https://github.com/lyswhut/lx-music-desktop/compare/v0.2.1...v0.2.2) - 2019-08-21
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复下载过程中出错重试5次都失败后不会自动开始下一个任务的Bug
|
||||
- 修复播放到一半URL过期时不会刷新URL直接播放下一首的问题
|
||||
|
||||
## [0.2.1](https://github.com/lyswhut/lx-music-desktop/compare/v0.2.0...v0.2.1) - 2019-08-20
|
||||
|
||||
### 优化
|
||||
|
||||
- 新增歌曲URL存储,当URL无效时才重新获取,以减少接口不稳定的影响
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复歌曲加载无法加载时自动切换混乱的Bug
|
||||
- 修复移除列表最后一首歌曲时播放器不停止播放的问题
|
||||
|
||||
## [0.2.0](https://github.com/lyswhut/lx-music-desktop/compare/v0.1.6...v0.2.0) - 2019-08-20
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增**百度音乐**排行榜及其音乐直接试听与下载
|
||||
- 新增网易云排行榜音乐直接试听与下载(目前仅支持128k音质)
|
||||
- 新增酷狗排行榜音乐直接试听与下载(目前仅支持128k音质)
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复更新弹窗历史版本描述多余的换行问题
|
||||
- 修复歌曲无法播放的情况下歌词仍会播放的问题
|
||||
|
||||
## [0.1.6](https://github.com/lyswhut/lx-music-desktop/compare/v0.1.5...v0.1.6) - 2019-08-19
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复列表多选音源限制Bug
|
||||
|
||||
## [0.1.5](https://github.com/lyswhut/lx-music-desktop/compare/v0.1.4...v0.1.5) - 2019-08-19
|
||||
|
||||
### 新增
|
||||
|
||||
49
README.md
49
README.md
@@ -1,24 +1,34 @@
|
||||
# 洛雪音乐助手桌面版
|
||||
<p align="center"><a href="https://github.com/lyswhut/lx-music-desktop"><img width="200" src="https://github.com/lyswhut/lx-music-desktop/blob/master/doc/images/icon.png" alt="lx-music logo"></a></p>
|
||||
|
||||
[![GitHub release][1]][2]
|
||||
<p align="center">
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/releases"><img src="https://img.shields.io/github/release/lyswhut/lx-music-desktop" alt="Release version"></a>
|
||||
<a href="https://ci.appveyor.com/project/lyswhut/lx-music-desktop"><img src="https://ci.appveyor.com/api/projects/status/flrsqd5ymp8fnte5?svg=true" alt="Build status"></a>
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/releases"><img src="https://img.shields.io/github/downloads/lyswhut/lx-music-desktop/latest/total" alt="Downloads"></a>
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/tree/dev"><img src="https://img.shields.io/github/package-json/v/lyswhut/lx-music-desktop/dev" alt="Dev branch version"></a>
|
||||
<!-- <a href="https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE"><img src="https://img.shields.io/github/license/lyswhut/lx-music-desktop" alt="License"></a> -->
|
||||
</p>
|
||||
|
||||
<!-- [![GitHub release][1]][2]
|
||||
[![Build status][3]][4]
|
||||
[![GitHub Releases Download][5]][6]
|
||||
[![dev branch][7]][8]
|
||||
<!-- [![GitHub license][9]][10] -->
|
||||
[![GitHub license][9]][10] -->
|
||||
|
||||
[1]: https://img.shields.io/github/release/lyswhut/lx-music-desktop
|
||||
<!-- [1]: https://img.shields.io/github/release/lyswhut/lx-music-desktop
|
||||
[2]: https://github.com/lyswhut/lx-music-desktop/releases
|
||||
[3]: https://ci.appveyor.com/api/projects/status/flrsqd5ymp8fnte5?svg=true
|
||||
[4]: https://ci.appveyor.com/project/lyswhut/lx-music-desktop
|
||||
[5]: https://img.shields.io/github/downloads/lyswhut/lx-music-desktop/latest/total
|
||||
<!-- [5]: https://img.shields.io/github/downloads/lyswhut/lx-music-desktop/total -->
|
||||
[5]: https://img.shields.io/github/downloads/lyswhut/lx-music-desktop/total
|
||||
[6]: https://github.com/lyswhut/lx-music-desktop/releases
|
||||
[7]: https://img.shields.io/github/package-json/v/lyswhut/lx-music-desktop/dev
|
||||
[8]: https://github.com/lyswhut/lx-music-desktop/tree/dev
|
||||
[9]: https://img.shields.io/github/license/lyswhut/lx-music-desktop
|
||||
<!-- [10]: https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE -->
|
||||
[10]: https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE -->
|
||||
|
||||
## 说明
|
||||
<h2 align="center">洛雪音乐助手桌面版</h2>
|
||||
|
||||
### 说明
|
||||
|
||||
一个基于 Electron + Vue 开发的 Windows 版音乐软件。
|
||||
|
||||
@@ -27,13 +37,20 @@
|
||||
- Electron 6.x
|
||||
- Vue 2.x
|
||||
|
||||
软件变化请查看:[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)<br>
|
||||
软件下载请转到:[发布页面](https://github.com/lyswhut/lx-music-desktop/releases)
|
||||
|
||||
其他说明:TODO
|
||||
|
||||
软件变化请查看:[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)
|
||||
#### 关于软件更新
|
||||
|
||||
感谢 <https://github.com/messoer> 提供的部分音乐API!
|
||||
软件启动时若发现新版本时会自动从本仓库下载安装包,下载完毕会弹窗提示更新。<br>
|
||||
若下载未完成时软件被关闭,下次启动软件会再次自动下载。<br>
|
||||
目前暂未添加跳过更新某个版本的功能。<br>
|
||||
|
||||
## 使用方法
|
||||
### 源码使用方法
|
||||
|
||||
环境要求:Node.js 12.x
|
||||
|
||||
```bash
|
||||
# 开发模式
|
||||
@@ -47,6 +64,14 @@ npm run pack
|
||||
|
||||
```
|
||||
|
||||
## License
|
||||
### UI界面
|
||||
|
||||
Apache License 2.0
|
||||
<p><a href="https://github.com/lyswhut/lx-music-desktop"><img width="100%" src="https://github.com/lyswhut/lx-music-desktop/blob/master/doc/images/app.png" alt="lx-music UI"></a></p>
|
||||
|
||||
### 致谢
|
||||
|
||||
感谢 [@messoer](https://github.com/messoer) 提供的部分音乐API!
|
||||
|
||||
### 许可证
|
||||
|
||||
[Apache License 2.0](https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE)
|
||||
|
||||
BIN
doc/images/app.png
Normal file
BIN
doc/images/app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
BIN
doc/images/icon.png
Normal file
BIN
doc/images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "0.1.5",
|
||||
"version": "0.2.2",
|
||||
"description": "一个免费的音乐下载助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
### 新增
|
||||
### 修复
|
||||
|
||||
- 新增搜索列表批量试听与下载功能
|
||||
- 新增排行榜列表批量试听与下载功能
|
||||
- 新增试听列表批量移除与下载功能
|
||||
- 新增下载列表批量开始、暂停与移除功能
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化歌曲切换机制
|
||||
- 修复下载过程中出错重试5次都失败后不会自动开始下一个任务的Bug
|
||||
- 修复播放到一半URL过期时不会刷新URL直接播放下一首的问题
|
||||
|
||||
@@ -7,11 +7,12 @@ const clearAssets = require('./utils/clearAssets')
|
||||
const updateVersionFile = require('./utils/updateChangeLog')
|
||||
// const copyFile = require('./utils/copyFile')
|
||||
// const githubRelease = require('./utils/githubRelease')
|
||||
const { parseArgv } = require('./utils')
|
||||
// const { parseArgv } = require('./utils')
|
||||
|
||||
const run = async() => {
|
||||
const params = parseArgv(process.argv.slice(2))
|
||||
const bak = await updateVersionFile(params.ver)
|
||||
// const params = parseArgv(process.argv.slice(2))
|
||||
// const bak = await updateVersionFile(params.ver)
|
||||
const bak = await updateVersionFile(process.argv.slice(2)[0])
|
||||
|
||||
try {
|
||||
console.log(chalk.blue('Clearing assets...'))
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
{
|
||||
"version": "0.1.5",
|
||||
"desc": "<h3>新增</h3>\n<ul>\n<li>新增搜索列表批量试听与下载功能</li>\n<li>新增排行榜列表批量试听与下载功能</li>\n<li>新增试听列表批量移除与下载功能</li>\n<li>新增下载列表批量开始、暂停与移除功能</li>\n</ul>\n<h3>优化</h3>\n<ul>\n<li>优化歌曲切换机制</li>\n</ul>\n",
|
||||
"version": "0.2.2",
|
||||
"desc": "<h3>修复</h3>\n<ul>\n<li>修复下载过程中出错重试5次都失败后不会自动开始下一个任务的Bug</li>\n<li>修复播放到一半URL过期时不会刷新URL直接播放下一首的问题</li>\n</ul>\n",
|
||||
"history": [
|
||||
{
|
||||
"version": "0.2.1",
|
||||
"desc": "<h3>优化</h3>\n<ul>\n<li>新增歌曲URL存储,当URL无效时才重新获取,以减少接口不稳定的影响</li>\n</ul>\n<h3>修复</h3>\n<ul>\n<li>修复歌曲加载无法加载时自动切换混乱的Bug</li>\n<li>修复移除列表最后一首歌曲时播放器不停止播放的问题</li>\n</ul>\n"
|
||||
},
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"desc": "<h3>新增</h3>\n<ul>\n<li>新增<strong>百度音乐</strong>排行榜及其音乐直接试听与下载</li>\n<li>新增网易云排行榜音乐直接试听与下载(目前仅支持128k音质)</li>\n<li>新增酷狗排行榜音乐直接试听与下载(目前仅支持128k音质)</li>\n</ul>\n<h3>修复</h3>\n<ul>\n<li>修复更新弹窗历史版本描述多余的换行问题</li>\n<li>修复歌曲无法播放的情况下歌词仍会播放的问题</li>\n</ul>\n"
|
||||
},
|
||||
{
|
||||
"version": "0.1.6",
|
||||
"desc": "<h3>修复</h3>\n<ul>\n<li>修复列表多选音源限制Bug</li>\n</ul>\n"
|
||||
},
|
||||
{
|
||||
"version": "0.1.5",
|
||||
"desc": "<h3>新增</h3>\n<ul>\n<li>新增搜索列表批量试听与下载功能</li>\n<li>新增排行榜列表批量试听与下载功能</li>\n<li>新增试听列表批量移除与下载功能</li>\n<li>新增下载列表批量开始、暂停与移除功能</li>\n</ul>\n<h3>优化</h3>\n<ul>\n<li>优化歌曲切换机制</li>\n</ul>\n"
|
||||
},
|
||||
{
|
||||
"version": "0.1.4",
|
||||
"desc": "<h3>新增</h3>\n<ul>\n<li>新增音乐来源切换,可到设置页面-基本设置 look look !</li>\n<li>为搜索结果列表添加多选功能。<br>\nP.S:暂时没想好多选后的操作按钮放哪…</li>\n</ul>\n<h3>优化</h3>\n<ul>\n<li>重构与改进checkbox组件,使其支持不定选中状态</li>\n<li>完善上一个版本的http请求封装并切换部分请求到该方法上</li>\n<li>优化其他一些细节</li>\n</ul>\n"
|
||||
|
||||
@@ -53,6 +53,7 @@ export default {
|
||||
},
|
||||
defaultList: {
|
||||
handler(n) {
|
||||
// console.log(n)
|
||||
this.electronStore.set('list.defaultList', n)
|
||||
},
|
||||
deep: true,
|
||||
@@ -110,10 +111,11 @@ export default {
|
||||
},
|
||||
initPlayList() {
|
||||
let defaultList = this.electronStore.get('list.defaultList')
|
||||
// console.log(defaultList)
|
||||
if (defaultList) {
|
||||
defaultList.list.forEach(m => {
|
||||
m.typeUrl = {}
|
||||
})
|
||||
// defaultList.list.forEach(m => {
|
||||
// m.typeUrl = {}
|
||||
// })
|
||||
this.initDefaultList(defaultList)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -43,6 +43,7 @@ import Lyric from 'lrc-file-parser'
|
||||
import { rendererSend } from '../../../common/icp'
|
||||
import { formatPlayTime2, getRandom, checkPath } from '../../utils'
|
||||
import { mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import { requestMsg } from '../../utils/message'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -61,12 +62,16 @@ export default {
|
||||
name: '^',
|
||||
singer: '^',
|
||||
},
|
||||
targetSong: null,
|
||||
pregessWidth: 0,
|
||||
lyric: {
|
||||
lrc: null,
|
||||
text: '',
|
||||
line: 0,
|
||||
},
|
||||
delayNextTimeout: null,
|
||||
audioErrorTime: 0,
|
||||
// retryNum: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -117,8 +122,13 @@ export default {
|
||||
? n.findIndex(s => s.musicInfo.songmid === this.musicInfo.songmid)
|
||||
: n.findIndex(s => s.songmid === this.musicInfo.songmid)
|
||||
if (index < 0) {
|
||||
this.fixPlayIndex(this.playIndex - 1)
|
||||
if (n.length) this.handleNext()
|
||||
// console.log(this.playIndex)
|
||||
if (n.length) {
|
||||
this.fixPlayIndex(this.playIndex - 1)
|
||||
this.handleNext()
|
||||
} else {
|
||||
this.setPlayIndex(-1)
|
||||
}
|
||||
} else {
|
||||
this.fixPlayIndex(index)
|
||||
}
|
||||
@@ -137,6 +147,7 @@ export default {
|
||||
'fixPlayIndex',
|
||||
'resetChangePlay',
|
||||
]),
|
||||
...mapMutations('list', ['updateMusicInfo']),
|
||||
init() {
|
||||
this.audio = document.createElement('audio')
|
||||
this.audio.controls = false
|
||||
@@ -161,10 +172,17 @@ export default {
|
||||
this.handleNext()
|
||||
})
|
||||
this.audio.addEventListener('error', () => {
|
||||
// console.log('code', this.audio.error.code)
|
||||
if (!this.musicInfo.songmid) return
|
||||
console.log('出错')
|
||||
if (this.audio.error.code !== 1 && this.retryNum < 3) { // 若音频URL无效则尝试刷新3次URL
|
||||
// console.log(this.retryNum)
|
||||
this.audioErrorTime = this.audio.currentTime // 记录出错的播放时间
|
||||
this.retryNum++
|
||||
this.setUrl(this.list[this.playIndex], true)
|
||||
return
|
||||
}
|
||||
this.stopPlay()
|
||||
this.status = '加载出错'
|
||||
this.sendProgressEvent(this.progress, 'error')
|
||||
|
||||
// let urls = this.player_info.targetSong.urls
|
||||
@@ -182,10 +200,16 @@ export default {
|
||||
// } else {
|
||||
// this.handleNext()
|
||||
// }
|
||||
this.handleNext()
|
||||
this.status = '音频加载出错,5 秒后切换下一首'
|
||||
this.addDelayNextTimeout()
|
||||
})
|
||||
this.audio.addEventListener('loadeddata', () => {
|
||||
this.maxPlayTime = this.audio.duration
|
||||
if (this.audioErrorTime) {
|
||||
this.audio.currentTime = this.audioErrorTime
|
||||
this.audioErrorTime = 0
|
||||
}
|
||||
if (!this.targetSong.interval && this.listId != 'download') this.updateMusicInfo({ index: this.playIndex, data: { interval: formatPlayTime2(this.maxPlayTime) } })
|
||||
this.status = '音乐加载中...'
|
||||
})
|
||||
// this.audio.addEventListener('loadstart', () => {
|
||||
@@ -228,7 +252,10 @@ export default {
|
||||
},
|
||||
play() {
|
||||
console.log('play', this.playIndex)
|
||||
let targetSong = this.list[this.playIndex]
|
||||
this.checkDelayNextTimeout()
|
||||
let targetSong = this.targetSong = this.list[this.playIndex]
|
||||
this.retryNum = 0
|
||||
this.audioErrorTime = 0
|
||||
|
||||
if (this.listId == 'download') {
|
||||
if (!checkPath(targetSong.filePath) || !targetSong.isComplate || /\.ape$/.test(targetSong.filePath)) {
|
||||
@@ -250,6 +277,20 @@ export default {
|
||||
this.setLrc(targetSong)
|
||||
}
|
||||
},
|
||||
checkDelayNextTimeout() {
|
||||
console.log(this.delayNextTimeout)
|
||||
if (this.delayNextTimeout) {
|
||||
clearTimeout(this.delayNextTimeout)
|
||||
this.delayNextTimeout = null
|
||||
}
|
||||
},
|
||||
addDelayNextTimeout() {
|
||||
this.checkDelayNextTimeout()
|
||||
this.delayNextTimeout = setTimeout(() => {
|
||||
this.delayNextTimeout = null
|
||||
this.handleNext()
|
||||
}, 5000)
|
||||
},
|
||||
handleNext() {
|
||||
// if (this.list.listName === null) return
|
||||
let list
|
||||
@@ -262,7 +303,7 @@ export default {
|
||||
}
|
||||
if (!list.length) return this.setPlayIndex(-1)
|
||||
let playIndex = this.list === list ? this.playIndex : list.indexOf(this.list[this.playIndex])
|
||||
|
||||
// console.log(playIndex)
|
||||
let index
|
||||
switch (this.setting.player.togglePlayMethod) {
|
||||
case 'listLoop':
|
||||
@@ -321,28 +362,27 @@ export default {
|
||||
this.musicInfo.img = null
|
||||
},
|
||||
getPlayType(highQuality, songInfo) {
|
||||
switch (songInfo.source) {
|
||||
case 'wy':
|
||||
case 'kg':
|
||||
return '128k'
|
||||
}
|
||||
let type = songInfo._types['192k'] ? '192k' : '128k'
|
||||
if (highQuality && songInfo._types['320k']) type = '320k'
|
||||
return type
|
||||
},
|
||||
setUrl(targetSong) {
|
||||
setUrl(targetSong, isRefresh) {
|
||||
let type = this.getPlayType(this.setting.player.highQuality, targetSong)
|
||||
this.musicInfo.url = targetSong.typeUrl[type]
|
||||
this.status = '歌曲链接获取中...'
|
||||
|
||||
let urlP = this.musicInfo.url
|
||||
? Promise.resolve()
|
||||
: this.getUrl({ musicInfo: targetSong, type }).then(() => {
|
||||
this.musicInfo.url = targetSong.typeUrl[type]
|
||||
})
|
||||
|
||||
urlP.then(() => {
|
||||
this.audio.src = this.musicInfo.url
|
||||
return this.getUrl({ musicInfo: targetSong, type, isRefresh }).then(() => {
|
||||
this.audio.src = this.musicInfo.url = targetSong.typeUrl[type]
|
||||
}).catch(err => {
|
||||
if (err.message == requestMsg.cancelRequest) return
|
||||
this.status = err.message
|
||||
setTimeout(() => {
|
||||
this.handleNext()
|
||||
}, 2000)
|
||||
this.addDelayNextTimeout()
|
||||
return Promise.reject(err)
|
||||
})
|
||||
},
|
||||
setImg(targetSong) {
|
||||
@@ -366,7 +406,7 @@ export default {
|
||||
lrcP
|
||||
.then(() => {
|
||||
this.lyric.lrc.setLyric(this.musicInfo.lrc)
|
||||
if (this.isPlay) this.lyric.lrc.play(this.audio.currentTime * 1000)
|
||||
if (this.isPlay && (this.musicInfo.url || this.listId == 'download')) this.lyric.lrc.play(this.audio.currentTime * 1000)
|
||||
})
|
||||
.catch(err => {
|
||||
this.status = err.message
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template lang="pug">
|
||||
button(:class="[$style.btn, min ? $style.min : '']" @click="$emit('click', $event)")
|
||||
button(:class="[$style.btn, min ? $style.min : '']" :disabled="disabled" @click="$emit('click', $event)")
|
||||
slot
|
||||
</template>
|
||||
|
||||
@@ -9,6 +9,10 @@ export default {
|
||||
min: {
|
||||
type: Boolean,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -27,6 +31,9 @@ export default {
|
||||
outline: none;
|
||||
transition: background-color 0.2s ease;
|
||||
background-color: @color-btn-background;
|
||||
&[disabled] {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: @color-theme_2-hover;
|
||||
|
||||
@@ -5,7 +5,7 @@ material-modal(:show="show" :bg-close="bgClose" @close="handleClose")
|
||||
| {{ info.name }}
|
||||
br
|
||||
| {{ info.singer }}
|
||||
material-btn(:class="$style.btn" :key="type.type" @click="handleClick(type.type)" v-for="type in info.types") {{getTypeName(type.type)}} {{ type.type.toUpperCase() }}{{ type.size && ` - ${type.size.toUpperCase()}` }}
|
||||
material-btn(:class="$style.btn" :title="!checkSource(type.type) && '目前酷狗、网易云音源仅支持下载128k音质'" :disabled="!checkSource(type.type)" :key="type.type" @click="handleClick(type.type)" v-for="type in info.types") {{getTypeName(type.type)}} {{ type.type.toUpperCase() }}{{ type.size && ` - ${type.size.toUpperCase()}` }}
|
||||
|
||||
</template>
|
||||
|
||||
@@ -49,6 +49,16 @@ export default {
|
||||
return '普通音质'
|
||||
}
|
||||
},
|
||||
checkSource(type) {
|
||||
switch (this.musicInfo.source) {
|
||||
case 'wy':
|
||||
case 'kg':
|
||||
return type == '128k'
|
||||
|
||||
default:
|
||||
return true
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -37,18 +37,6 @@ export default {
|
||||
handleClose() {
|
||||
this.$emit('close')
|
||||
},
|
||||
getTypeName(type) {
|
||||
switch (type) {
|
||||
case 'flac':
|
||||
case 'ape':
|
||||
return '无损音质'
|
||||
case '320k':
|
||||
return '高品音质'
|
||||
case '192k':
|
||||
case '128k':
|
||||
return '普通音质'
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -127,7 +127,7 @@ export default {
|
||||
h3 {
|
||||
padding: 5px 0 3px;
|
||||
}
|
||||
padding-left: 15px;
|
||||
padding: 0 15px;
|
||||
+ .item {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ const checkList = (list, musicInfo, type) => list.some(s => s.musicInfo.songmid
|
||||
const getStartTask = (list, downloadStatus, maxDownloadNum) => {
|
||||
let downloadCount = 0
|
||||
const waitList = list.filter(item => item.status == downloadStatus.WAITING ? true : (item.status === downloadStatus.RUN && ++downloadCount && false))
|
||||
console.log(downloadCount, waitList)
|
||||
// console.log(downloadCount, waitList)
|
||||
return downloadCount < maxDownloadNum && waitList.length > 0 && waitList.shift()
|
||||
}
|
||||
|
||||
@@ -70,8 +70,9 @@ const addTask = (list, type, store) => {
|
||||
})
|
||||
}
|
||||
|
||||
const refreshUrl = downloadInfo => {
|
||||
return music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise
|
||||
const getUrl = (downloadInfo, isRefresh) => {
|
||||
const url = downloadInfo.musicInfo.typeUrl[downloadInfo.type]
|
||||
return url && !isRefresh ? Promise.resolve({ url }) : music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise
|
||||
}
|
||||
|
||||
// actions
|
||||
@@ -116,12 +117,12 @@ const actions = {
|
||||
// 检查是否可以开始任务
|
||||
if (downloadInfo && downloadInfo != state.downloadStatus.WAITING) commit('setStatus', { downloadInfo, status: state.downloadStatus.WAITING })
|
||||
let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum)
|
||||
if (!result) return downloadInfo && commit('setStatus', { downloadInfo, status: state.downloadStatus.WAITING })
|
||||
if (!result) return
|
||||
if (!downloadInfo) downloadInfo = result
|
||||
|
||||
// 开始任务
|
||||
commit('setStatusText', { downloadInfo, text: '任务初始化中' })
|
||||
commit('onDownload', downloadInfo)
|
||||
commit('setStatusText', { downloadInfo, text: '任务初始化中' })
|
||||
let msg = checkPath(rootState.setting.download.savePath)
|
||||
if (msg) return commit('setStatusText', '检查下载目录出错: ' + msg)
|
||||
const _this = this
|
||||
@@ -137,15 +138,18 @@ const actions = {
|
||||
console.log('on complate')
|
||||
},
|
||||
onError(err) {
|
||||
console.log(err.message)
|
||||
// console.log(err.code, err.message)
|
||||
commit('onError', downloadInfo)
|
||||
// console.log(tryNum[downloadInfo.key])
|
||||
if (++tryNum[downloadInfo.key] > 5) return
|
||||
if (++tryNum[downloadInfo.key] > 5) {
|
||||
_this.dispatch('download/startTask')
|
||||
return
|
||||
}
|
||||
let code
|
||||
if (err.message.includes('Response status was')) {
|
||||
code = err.message.replace(/Response status was (\d+)$/, '$1')
|
||||
} if (err.code === 'ETIMEDOUT') {
|
||||
code = 'ETIMEDOUT'
|
||||
} else if (err.code === 'ETIMEDOUT' || err.code == 'ENOTFOUND') {
|
||||
code = err.code
|
||||
} else {
|
||||
console.log('Download failed, Attempting Retry')
|
||||
dls[downloadInfo.key].resume()
|
||||
@@ -157,8 +161,9 @@ const actions = {
|
||||
case '403':
|
||||
case '410':
|
||||
case 'ETIMEDOUT':
|
||||
case 'ENOTFOUND':
|
||||
commit('setStatusText', { downloadInfo, text: '链接失效,正在刷新链接' })
|
||||
refreshUrl(downloadInfo).then(result => {
|
||||
getUrl(downloadInfo, true).then(result => {
|
||||
commit('updateUrl', { downloadInfo, url: result.url })
|
||||
commit('setStatusText', { downloadInfo, text: '链接刷新成功' })
|
||||
dls[downloadInfo.key].url = dls[downloadInfo.key].requestURL = result.url
|
||||
@@ -189,22 +194,25 @@ const actions = {
|
||||
commit('resumeTask', downloadInfo)
|
||||
},
|
||||
}
|
||||
let p = options.url ? Promise.resolve() : refreshUrl(downloadInfo).then(result => {
|
||||
commit('setStatusText', { downloadInfo, text: '获取URL中...' })
|
||||
let p = options.url ? Promise.resolve() : getUrl(downloadInfo).then(result => {
|
||||
commit('updateUrl', { downloadInfo, url: result.url })
|
||||
if (!result.url) return Promise.reject(new Error('获取URL失败'))
|
||||
options.url = result.url
|
||||
}).catch(err => {
|
||||
commit('onError', downloadInfo)
|
||||
commit('setStatusText', { downloadInfo, text: err.message })
|
||||
return Promise.reject(err)
|
||||
})
|
||||
p.then(() => {
|
||||
tryNum[downloadInfo.key] = 0
|
||||
dls[downloadInfo.key] = download(options)
|
||||
}).catch(err => {
|
||||
// console.log(err.message)
|
||||
commit('onError', downloadInfo)
|
||||
commit('setStatusText', { downloadInfo, text: err.message })
|
||||
this.dispatch('download/startTask')
|
||||
})
|
||||
},
|
||||
startTaskMultiple({ state, rootState }, list) {
|
||||
// startTaskMultiple({ state, rootState }, list) {
|
||||
|
||||
},
|
||||
// },
|
||||
removeTask({ commit, state }, index) {
|
||||
let info = state.list[index]
|
||||
if (state.list[index].status == state.downloadStatus.RUN) {
|
||||
|
||||
@@ -39,6 +39,9 @@ const mutations = {
|
||||
defaultListRemove(state, index) {
|
||||
state.defaultList.list.splice(index, 1)
|
||||
},
|
||||
updateMusicInfo(state, { index, data }) {
|
||||
Object.assign(state.defaultList.list[index], data)
|
||||
},
|
||||
defaultListRemoveMultiple(state, list) {
|
||||
list.forEach(musicInfo => {
|
||||
let index = state.defaultList.list.indexOf(musicInfo)
|
||||
|
||||
@@ -22,8 +22,9 @@ const getters = {
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
getUrl({ commit, state }, { musicInfo, type }) {
|
||||
getUrl({ commit, state }, { musicInfo, type, isRefresh }) {
|
||||
if (urlRequest && urlRequest.cancelHttp) urlRequest.cancelHttp()
|
||||
if (musicInfo.typeUrl[type] && !isRefresh) return Promise.resolve()
|
||||
urlRequest = music[musicInfo.source].getMusicUrl(musicInfo, type)
|
||||
return urlRequest.promise.then(result => {
|
||||
commit('setUrl', { musicInfo, url: result.url, type })
|
||||
@@ -35,7 +36,6 @@ const actions = {
|
||||
if (picRequest && picRequest.cancelHttp) picRequest.cancelHttp()
|
||||
picRequest = music[musicInfo.source].getPic(musicInfo)
|
||||
return picRequest.promise.then(url => {
|
||||
console.log(url)
|
||||
commit('getPic', { musicInfo, url })
|
||||
}).finally(() => {
|
||||
picRequest = null
|
||||
@@ -73,6 +73,7 @@ const mutations = {
|
||||
setPlayIndex(state, index) {
|
||||
state.playIndex = index
|
||||
state.changePlay = true
|
||||
// console.log(state.changePlay)
|
||||
},
|
||||
fixPlayIndex(state, index) {
|
||||
state.playIndex = index
|
||||
|
||||
@@ -13,9 +13,9 @@ export default {
|
||||
if (source != null) state.setting.leaderboard.source = source
|
||||
},
|
||||
setNewVersion(state, val) {
|
||||
val.history.forEach(ver => {
|
||||
ver.desc = ver.desc.replace(/\n/g, '<br>')
|
||||
})
|
||||
// val.history.forEach(ver => {
|
||||
// ver.desc = ver.desc.replace(/\n/g, '<br>')
|
||||
// })
|
||||
// val.desc = val.desc.replace(/\n/g, '<br>')
|
||||
state.version.newVersion = val
|
||||
},
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import kw_api_messoer from './kw/api-messoer'
|
||||
import kw_api_temp from './kw/api-temp'
|
||||
import tx_api_messoer from './tx/api-messoer'
|
||||
import kg_api_messoer from './kg/api-messoer'
|
||||
import wy_api_messoer from './wy/api-messoer'
|
||||
import bd_api_messoer from './bd/api-messoer'
|
||||
|
||||
const apis = {
|
||||
kw_api_messoer,
|
||||
tx_api_messoer,
|
||||
kg_api_messoer,
|
||||
wy_api_messoer,
|
||||
bd_api_messoer,
|
||||
kw_api_temp,
|
||||
}
|
||||
|
||||
@@ -22,6 +28,12 @@ export default source => {
|
||||
switch (source) {
|
||||
case 'tx':
|
||||
return getAPI('tx')
|
||||
case 'kg':
|
||||
return getAPI('kg')
|
||||
case 'wy':
|
||||
return getAPI('wy')
|
||||
case 'bd':
|
||||
return getAPI('bd')
|
||||
default:
|
||||
return getAPI('kw')
|
||||
}
|
||||
|
||||
37
src/renderer/utils/music/bd/api-messoer.js
Normal file
37
src/renderer/utils/music/bd/api-messoer.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { httpFatch } from '../../request'
|
||||
import { requestMsg } from '../../message'
|
||||
|
||||
const api_messoer = {
|
||||
getMusicUrl(songInfo, type) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/baidu/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getPic(songInfo, size = '500') {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/baidu/pic?id=${songInfo.songmid}&imageSize=${size}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/baidu/lrc?id=${songInfo.songmid}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
}
|
||||
|
||||
export default api_messoer
|
||||
21
src/renderer/utils/music/bd/index.js
Normal file
21
src/renderer/utils/music/bd/index.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import leaderboard from './leaderboard'
|
||||
import api_source from '../api-source'
|
||||
import musicInfo from './musicInfo'
|
||||
|
||||
const bd = {
|
||||
leaderboard,
|
||||
getMusicUrl(songInfo, type) {
|
||||
return api_source('bd').getMusicUrl(songInfo, type)
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
return api_source('bd').getLyric(songInfo)
|
||||
},
|
||||
getPic(songInfo) {
|
||||
return api_source('bd').getPic(songInfo)
|
||||
},
|
||||
getMusicInfo(songInfo) {
|
||||
return musicInfo.getMusicInfo(songInfo.songmid)
|
||||
},
|
||||
}
|
||||
|
||||
export default bd
|
||||
132
src/renderer/utils/music/bd/leaderboard.js
Normal file
132
src/renderer/utils/music/bd/leaderboard.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import { httpFatch } from '../../request'
|
||||
// import { formatPlayTime } from '../../index'
|
||||
// import jshtmlencode from 'js-htmlencode'
|
||||
|
||||
export default {
|
||||
limit: 20,
|
||||
list: [
|
||||
{
|
||||
id: 'bdrgb',
|
||||
name: '热歌榜',
|
||||
bangid: '2',
|
||||
},
|
||||
{
|
||||
id: 'bdxgb',
|
||||
name: '新歌榜',
|
||||
bangid: '1',
|
||||
},
|
||||
{
|
||||
id: 'bdycb',
|
||||
name: '原创榜',
|
||||
bangid: '200',
|
||||
},
|
||||
{
|
||||
id: 'bdhyjqb',
|
||||
name: '华语榜',
|
||||
bangid: '20',
|
||||
},
|
||||
{
|
||||
id: 'bdomjqb',
|
||||
name: '欧美榜',
|
||||
bangid: '21',
|
||||
},
|
||||
{
|
||||
id: 'bdwugqb',
|
||||
name: '网络榜',
|
||||
bangid: '25',
|
||||
},
|
||||
{
|
||||
id: 'bdjdlgb',
|
||||
name: '老歌榜',
|
||||
bangid: '22',
|
||||
},
|
||||
{
|
||||
id: 'bdysjqb',
|
||||
name: '影视金曲榜',
|
||||
bangid: '24',
|
||||
},
|
||||
{
|
||||
id: 'bdqgdcb',
|
||||
name: '情歌对唱榜',
|
||||
bangid: '23',
|
||||
},
|
||||
{
|
||||
id: 'bdygb',
|
||||
name: '摇滚榜',
|
||||
bangid: '11',
|
||||
},
|
||||
],
|
||||
getUrl(id, p) {
|
||||
return `http://musicmini.qianqian.com/2018/static/bangdan/bangdanList_${id}_${p}.html`
|
||||
},
|
||||
regExps: {
|
||||
item: /data-song="({.+?})"/g,
|
||||
info: /{total[\s:]+"(\d+)", size[\s:]+"(\d+)", page[\s:]+"(\d+)"}/,
|
||||
},
|
||||
requestObj: null,
|
||||
getData(url) {
|
||||
if (this.requestObj) this.requestObj.cancelHttp()
|
||||
this.requestObj = httpFatch(url)
|
||||
return this.requestObj.promise
|
||||
},
|
||||
filterData(rawList) {
|
||||
// console.log(rawList)
|
||||
return rawList.map(item => {
|
||||
const types = []
|
||||
const _types = {}
|
||||
let size = null
|
||||
types.push({ type: '128k', size })
|
||||
_types['128k'] = {
|
||||
size,
|
||||
}
|
||||
if (item.biaoshi) {
|
||||
types.push({ type: '320k', size })
|
||||
_types['320k'] = {
|
||||
size,
|
||||
}
|
||||
types.push({ type: 'flac', size })
|
||||
_types['flac'] = {
|
||||
size,
|
||||
}
|
||||
}
|
||||
// types.reverse()
|
||||
|
||||
return {
|
||||
singer: item.song_artist.replace(',', '、'),
|
||||
name: item.song_title,
|
||||
albumName: item.album_title,
|
||||
albumId: item.album_id,
|
||||
source: 'bd',
|
||||
interval: '',
|
||||
songmid: item.song_id,
|
||||
img: null,
|
||||
lrc: null,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
}
|
||||
})
|
||||
},
|
||||
parseData(rawData) {
|
||||
// return rawData.map(item => JSON.parse(item.replace(this.regExps.item, '$1').replace(/"/g, '"').replace(/\\\//g, '/').replace(/(@s_1,w_)\d+(,h_)\d+/, '$1500$2500')))
|
||||
return rawData.map(item => JSON.parse(item.replace(this.regExps.item, '$1').replace(/"/g, '"').replace(/\\\//g, '/')))
|
||||
},
|
||||
getList(id, page) {
|
||||
let type = this.list.find(s => s.id === id)
|
||||
if (!type) return Promise.reject()
|
||||
return this.getData(this.getUrl(type.bangid, page)).then(({ body }) => {
|
||||
let result = body.match(this.regExps.item)
|
||||
if (!result) return Promise.reject(new Error('匹配list失败'))
|
||||
let info = body.match(this.regExps.info)
|
||||
if (!info) return Promise.reject(new Error('匹配info失败'))
|
||||
const list = this.filterData(this.parseData(result))
|
||||
this.limit = parseInt(info[2])
|
||||
return {
|
||||
total: parseInt(info[1]),
|
||||
list,
|
||||
limit: this.limit,
|
||||
page: parseInt(info[3]),
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
11
src/renderer/utils/music/bd/musicInfo.js
Normal file
11
src/renderer/utils/music/bd/musicInfo.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { httpFatch } from '../../request'
|
||||
|
||||
export default {
|
||||
getMusicInfo(songmid) {
|
||||
const requestObj = httpFatch(`https://musicapi.qianqian.com/v1/restserver/ting?method=baidu.ting.song.getSongLink&format=json&from=bmpc&version=1.0.0&version_d=11.1.6.0&songid=${songmid}&type=1&res=1&s_protocol=1&aac=2&project=tpass`)
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.error_code == 22000 ? body.reqult.songinfo : Promise.reject(new Error('获取音乐信息失败'))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import kw from './kw'
|
||||
import kg from './kg'
|
||||
import tx from './tx'
|
||||
import wy from './wy'
|
||||
import bd from './bd'
|
||||
export default {
|
||||
sources: [
|
||||
{
|
||||
@@ -20,9 +21,14 @@ export default {
|
||||
name: '网易音乐',
|
||||
id: 'wy',
|
||||
},
|
||||
{
|
||||
name: '百度音乐',
|
||||
id: 'bd',
|
||||
},
|
||||
],
|
||||
kw,
|
||||
kg,
|
||||
tx,
|
||||
wy,
|
||||
bd,
|
||||
}
|
||||
|
||||
37
src/renderer/utils/music/kg/api-messoer.js
Normal file
37
src/renderer/utils/music/kg/api-messoer.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { httpFatch } from '../../request'
|
||||
import { requestMsg } from '../../message'
|
||||
|
||||
const api_messoer = {
|
||||
getMusicUrl(songInfo, type) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/kugou/url?id=${songInfo._types[type].hash}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getPic(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/kugou/pic?id=${songInfo.hash}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/kugou/lrc?id=${songInfo.hash}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
}
|
||||
|
||||
export default api_messoer
|
||||
@@ -1,7 +1,18 @@
|
||||
import leaderboard from './leaderboard'
|
||||
import api_source from '../api-source'
|
||||
|
||||
|
||||
const kg = {
|
||||
leaderboard,
|
||||
getMusicUrl(songInfo, type) {
|
||||
return api_source('kg').getMusicUrl(songInfo, type)
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
return api_source('kg').getLyric(songInfo)
|
||||
},
|
||||
getPic(songInfo) {
|
||||
return api_source('kg').getPic(songInfo)
|
||||
},
|
||||
}
|
||||
|
||||
export default kg
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { httpGet, cancelHttp } from '../../request'
|
||||
import { formatPlayTime } from '../../index'
|
||||
import { formatPlayTime, sizeFormate } from '../../index'
|
||||
|
||||
export default {
|
||||
list: [
|
||||
@@ -89,18 +89,58 @@ export default {
|
||||
})
|
||||
},
|
||||
filterData(rawList) {
|
||||
return rawList.map(item => ({
|
||||
singer: item.singername,
|
||||
name: item.songname,
|
||||
albumName: item.album_name,
|
||||
albumId: item.album_id,
|
||||
songmid: item.audio_id,
|
||||
source: 'kg',
|
||||
interval: formatPlayTime(item.duration / 1000),
|
||||
img: null,
|
||||
lrc: null,
|
||||
typeUrl: {},
|
||||
}))
|
||||
// console.log(rawList)
|
||||
return rawList.map(item => {
|
||||
const types = []
|
||||
const _types = {}
|
||||
if (item.filesize !== 0) {
|
||||
let size = sizeFormate(item.filesize)
|
||||
types.push({ type: '128k', size, hash: item.hash })
|
||||
_types['128k'] = {
|
||||
size,
|
||||
hash: item.hash,
|
||||
}
|
||||
}
|
||||
if (item.filesize_320 !== 0) {
|
||||
let size = sizeFormate(item.filesize_320)
|
||||
types.push({ type: '320k', size, hash: item.hash_320 })
|
||||
_types['320k'] = {
|
||||
size,
|
||||
hash: item.hash_320,
|
||||
}
|
||||
}
|
||||
if (item.filesize_ape !== 0) {
|
||||
let size = sizeFormate(item.filesize_ape)
|
||||
types.push({ type: 'ape', size, hash: item.hash_ape })
|
||||
_types.ape = {
|
||||
size,
|
||||
hash: item.hash_ape,
|
||||
}
|
||||
}
|
||||
if (item.filesize_flac !== 0) {
|
||||
let size = sizeFormate(item.filesize_flac)
|
||||
types.push({ type: 'flac', size, hash: item.hash_flac })
|
||||
_types.flac = {
|
||||
size,
|
||||
hash: item.hash_flac,
|
||||
}
|
||||
}
|
||||
return {
|
||||
singer: item.singername,
|
||||
name: item.songname,
|
||||
albumName: item.album_name,
|
||||
albumId: item.album_id,
|
||||
songmid: item.audio_id,
|
||||
source: 'kg',
|
||||
interval: formatPlayTime(item.duration / 1000),
|
||||
img: null,
|
||||
lrc: null,
|
||||
hash: item.HASH,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
}
|
||||
})
|
||||
},
|
||||
getList(id, page) {
|
||||
let type = this.list.find(s => s.id === id)
|
||||
|
||||
@@ -3,8 +3,14 @@
|
||||
* @param {*} info
|
||||
* @param {*} type
|
||||
*/
|
||||
|
||||
const types = ['flac', 'ape', '320k', '192k', '128k']
|
||||
export const getMusicType = (info, type) => {
|
||||
switch (window.globalObj.apiSource) {
|
||||
case 'kg':
|
||||
case 'wy':
|
||||
return '128k'
|
||||
}
|
||||
const rangeType = types.slice(types.indexOf(type))
|
||||
for (const type of rangeType) {
|
||||
if (info._types[type]) return type
|
||||
|
||||
37
src/renderer/utils/music/wy/api-messoer.js
Normal file
37
src/renderer/utils/music/wy/api-messoer.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { httpFatch } from '../../request'
|
||||
import { requestMsg } from '../../message'
|
||||
|
||||
const api_messoer = {
|
||||
getMusicUrl(songInfo, type) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/netease/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getPic(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/netease/pic?id=${songInfo.songmid}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/netease/lrc?id=${songInfo.songmid}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout: 5000,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
}
|
||||
|
||||
export default api_messoer
|
||||
@@ -1,7 +1,17 @@
|
||||
import leaderboard from './leaderboard'
|
||||
import api_source from '../api-source'
|
||||
|
||||
const wy = {
|
||||
leaderboard,
|
||||
getMusicUrl(songInfo, type) {
|
||||
return api_source('wy').getMusicUrl(songInfo, type)
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
return api_source('wy').getLyric(songInfo)
|
||||
},
|
||||
getPic(songInfo) {
|
||||
return api_source('wy').getPic(songInfo)
|
||||
},
|
||||
}
|
||||
|
||||
export default wy
|
||||
|
||||
@@ -91,6 +91,42 @@ export default {
|
||||
filterData(rawList) {
|
||||
// console.log(rawList)
|
||||
return rawList.map(item => {
|
||||
const types = []
|
||||
const _types = {}
|
||||
let size
|
||||
switch (item.privilege.maxbr) {
|
||||
case 999000:
|
||||
size = null
|
||||
types.push({ type: 'flac', size })
|
||||
_types['flac'] = {
|
||||
size,
|
||||
}
|
||||
case 320000:
|
||||
size = null
|
||||
types.push({ type: '320k', size })
|
||||
_types['320k'] = {
|
||||
size,
|
||||
}
|
||||
case 192000:
|
||||
case 190000:
|
||||
size = null
|
||||
types.push({ type: '192k', size })
|
||||
_types['192k'] = {
|
||||
size,
|
||||
}
|
||||
// case '160000':
|
||||
|
||||
default:
|
||||
size = null
|
||||
types.push({ type: '128k', size })
|
||||
_types['128k'] = {
|
||||
size,
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
types.reverse()
|
||||
|
||||
return {
|
||||
singer: this.getSinger(item.artists),
|
||||
name: item.name,
|
||||
@@ -101,6 +137,8 @@ export default {
|
||||
songmid: item.id,
|
||||
img: item.album.picUrl,
|
||||
lrc: null,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -30,16 +30,16 @@
|
||||
td.break(style="width: 20%;") {{item.singer}}
|
||||
td.break(style="width: 22%;") {{item.albumName}}
|
||||
td(style="width: 18%;")
|
||||
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw' || (!isAPITemp && item.source == 'tx')" :download-btn="item.source == 'kw' || (!isAPITemp && item.source == 'tx')" :remove-btn="false" @btn-click="handleListBtnClick")
|
||||
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw' || !isAPITemp" :download-btn="item.source == 'kw' || !isAPITemp" :remove-btn="false" @btn-click="handleListBtnClick")
|
||||
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)') 下载
|
||||
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
|
||||
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
|
||||
td(style="width: 10%;") {{item.interval}}
|
||||
td(style="width: 10%;") {{item.interval || '--/--'}}
|
||||
div(:class="$style.pagination")
|
||||
material-pagination(:count="info.total" :limit="info.limit" :page="info.page" @btn-click="handleTogglePage")
|
||||
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
|
||||
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectdData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
|
||||
material-flow-btn(:show="isShowEditBtn" :remove-btn="false" @btn-click="handleFlowBtnClick")
|
||||
material-flow-btn(:show="isShowEditBtn && (source == 'kw' || !isAPITemp)" :remove-btn="false" @btn-click="handleFlowBtnClick")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -123,7 +123,7 @@ export default {
|
||||
this.clickIndex = index
|
||||
return
|
||||
}
|
||||
(this.source == 'kw' || (!this.isAPITemp && this.source == 'tx')) ? this.testPlay(index) : this.handleSearch(index)
|
||||
(this.source == 'kw' || !this.isAPITemp) ? this.testPlay(index) : this.handleSearch(index)
|
||||
this.clickTime = 0
|
||||
this.clickIndex = -1
|
||||
},
|
||||
@@ -170,7 +170,7 @@ export default {
|
||||
this.$router.push({
|
||||
path: 'search',
|
||||
query: {
|
||||
text: `${info.name} - ${info.singer}`,
|
||||
text: `${info.name} ${info.singer}`,
|
||||
},
|
||||
})
|
||||
},
|
||||
@@ -194,6 +194,11 @@ export default {
|
||||
this.isShowDownload = false
|
||||
},
|
||||
handleAddDownloadMultiple(type) {
|
||||
switch (this.source) {
|
||||
case 'kg':
|
||||
case 'wy':
|
||||
type = '128k'
|
||||
}
|
||||
this.createDownloadMultiple({ list: [...this.selectdData], type })
|
||||
this.resetSelect()
|
||||
this.isShowDownloadMultiple = false
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
|
||||
//- button.btn-secondary(type='button' @click.stop='handleRemove(index)') 删除
|
||||
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
|
||||
td(style="width: 10%;") {{item.interval}}
|
||||
td(style="width: 10%;") {{item.interval || '--/--'}}
|
||||
div(:class="$style.noItem" v-else)
|
||||
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
|
||||
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectdData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
|
||||
@@ -173,7 +173,8 @@ export default {
|
||||
this.selectdData = []
|
||||
},
|
||||
handleAddDownloadMultiple(type) {
|
||||
this.createDownloadMultiple({ list: [...this.selectdData], type })
|
||||
const list = this.setting.apiSource == 'temp' ? this.selectdData.filter(s => s.source == 'kw') : [...this.selectdData]
|
||||
this.createDownloadMultiple({ list, type })
|
||||
this.resetSelect()
|
||||
this.isShowDownloadMultiple = false
|
||||
},
|
||||
|
||||
@@ -86,6 +86,10 @@ div.scroll(:class="$style.setting")
|
||||
strong @messoer
|
||||
| !
|
||||
p.small 若有问题可 mail to:lyswhut@qq.com 或到 github 提交 issue
|
||||
p.small
|
||||
| 若觉得好用的话去GitHub点个
|
||||
strong star
|
||||
| 支持作者吧~
|
||||
p
|
||||
small By:
|
||||
| 落雪无痕
|
||||
|
||||
Reference in New Issue
Block a user