diff --git a/CHANGELOG.md b/CHANGELOG.md index aecc18a9..cdb7a356 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ 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.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 ### 修复 diff --git a/package.json b/package.json index 37c62dff..fa9c8d43 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-desktop", - "version": "0.1.6", + "version": "0.2.0", "description": "一个免费的音乐下载助手", "main": "./dist/electron/main.js", "scripts": { diff --git a/publish/changeLog.md b/publish/changeLog.md index 3eb86c66..5e1302d0 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,3 +1,8 @@ +### 新增 + +- 新增网易云排行榜音乐直接试听与下载(目前仅支持128k音质) +- 新增酷狗排行榜音乐直接试听与下载(目前仅支持128k音质) + ### 修复 - 修复更新弹窗历史版本描述多余的换行问题 diff --git a/publish/index.js b/publish/index.js index 15da4437..e1c26cf8 100644 --- a/publish/index.js +++ b/publish/index.js @@ -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...')) diff --git a/publish/version.json b/publish/version.json index 240a4636..c3989a5e 100644 --- a/publish/version.json +++ b/publish/version.json @@ -1,7 +1,11 @@ { - "version": "0.1.6", - "desc": "

修复

\n\n", + "version": "0.2.0", + "desc": "

新增

\n\n

修复

\n\n", "history": [ + { + "version": "0.1.6", + "desc": "

修复

\n\n" + }, { "version": "0.1.5", "desc": "

新增

\n\n

优化

\n\n" diff --git a/src/renderer/components/material/Btn.vue b/src/renderer/components/material/Btn.vue index be8a7193..45811c1a 100644 --- a/src/renderer/components/material/Btn.vue +++ b/src/renderer/components/material/Btn.vue @@ -1,5 +1,5 @@ @@ -9,6 +9,10 @@ export default { min: { type: Boolean, }, + disabled: { + type: Boolean, + default: false, + }, }, } @@ -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; diff --git a/src/renderer/components/material/DownloadModal.vue b/src/renderer/components/material/DownloadModal.vue index 239e75b8..a4ae5cdf 100644 --- a/src/renderer/components/material/DownloadModal.vue +++ b/src/renderer/components/material/DownloadModal.vue @@ -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()}` }} @@ -49,6 +49,16 @@ export default { return '普通音质' } }, + checkSource(type) { + switch (this.musicInfo.source) { + case 'wy': + case 'kg': + return type == '128k' + + default: + return true + } + }, }, } diff --git a/src/renderer/components/material/DownloadMultipleModal.vue b/src/renderer/components/material/DownloadMultipleModal.vue index 874fba15..705793c4 100644 --- a/src/renderer/components/material/DownloadMultipleModal.vue +++ b/src/renderer/components/material/DownloadMultipleModal.vue @@ -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 '普通音质' - } - }, }, } diff --git a/src/renderer/store/modules/download.js b/src/renderer/store/modules/download.js index b20070d5..2e614a01 100644 --- a/src/renderer/store/modules/download.js +++ b/src/renderer/store/modules/download.js @@ -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() } @@ -168,7 +168,9 @@ const actions = { console.log(err) _this.dispatch('download/startTask') }) + return } + _this.dispatch('download/startTask') }, // onStateChanged(state) { // console.log(state) @@ -191,20 +193,22 @@ const actions = { } let p = options.url ? Promise.resolve() : refreshUrl(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) { diff --git a/src/renderer/utils/music/api-source.js b/src/renderer/utils/music/api-source.js index 4fa59fdc..adeb2d2a 100644 --- a/src/renderer/utils/music/api-source.js +++ b/src/renderer/utils/music/api-source.js @@ -1,10 +1,14 @@ 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' const apis = { kw_api_messoer, tx_api_messoer, + kg_api_messoer, + wy_api_messoer, kw_api_temp, } @@ -22,6 +26,10 @@ export default source => { switch (source) { case 'tx': return getAPI('tx') + case 'kg': + return getAPI('kg') + case 'wy': + return getAPI('wy') default: return getAPI('kw') } diff --git a/src/renderer/utils/music/kg/api-messoer.js b/src/renderer/utils/music/kg/api-messoer.js new file mode 100644 index 00000000..017959af --- /dev/null +++ b/src/renderer/utils/music/kg/api-messoer.js @@ -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 diff --git a/src/renderer/utils/music/kg/index.js b/src/renderer/utils/music/kg/index.js index ac9a269a..4e83935a 100644 --- a/src/renderer/utils/music/kg/index.js +++ b/src/renderer/utils/music/kg/index.js @@ -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 diff --git a/src/renderer/utils/music/kg/leaderboard.js b/src/renderer/utils/music/kg/leaderboard.js index 2913b5d4..1e8c4eb9 100644 --- a/src/renderer/utils/music/kg/leaderboard.js +++ b/src/renderer/utils/music/kg/leaderboard.js @@ -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) diff --git a/src/renderer/utils/music/utils.js b/src/renderer/utils/music/utils.js index 14f0e1c6..94cd3b5f 100644 --- a/src/renderer/utils/music/utils.js +++ b/src/renderer/utils/music/utils.js @@ -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 diff --git a/src/renderer/utils/music/wy/api-messoer.js b/src/renderer/utils/music/wy/api-messoer.js new file mode 100644 index 00000000..2d8db5f0 --- /dev/null +++ b/src/renderer/utils/music/wy/api-messoer.js @@ -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 diff --git a/src/renderer/utils/music/wy/index.js b/src/renderer/utils/music/wy/index.js index 3dcb8fa2..accfa0d2 100644 --- a/src/renderer/utils/music/wy/index.js +++ b/src/renderer/utils/music/wy/index.js @@ -1,7 +1,18 @@ 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) { + console.log(api_source('wy')) + return api_source('wy').getLyric(songInfo) + }, + getPic(songInfo) { + return api_source('wy').getPic(songInfo) + }, } export default wy diff --git a/src/renderer/utils/music/wy/leaderboard.js b/src/renderer/utils/music/wy/leaderboard.js index 1f005b8f..e6167aaf 100644 --- a/src/renderer/utils/music/wy/leaderboard.js +++ b/src/renderer/utils/music/wy/leaderboard.js @@ -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: {}, } }) diff --git a/src/renderer/views/Leaderboard.vue b/src/renderer/views/Leaderboard.vue index 17d32d69..ecb1ea86 100644 --- a/src/renderer/views/Leaderboard.vue +++ b/src/renderer/views/Leaderboard.vue @@ -30,7 +30,7 @@ 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)') + @@ -39,7 +39,7 @@ 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 && (source == 'kw' || (!isAPITemp && source == 'tx'))" :remove-btn="false" @btn-click="handleFlowBtnClick") + material-flow-btn(:show="isShowEditBtn && (source == 'kw' || !isAPITemp)" :remove-btn="false" @btn-click="handleFlowBtnClick")