diff --git a/README.md b/README.md
index 451ae9c0..dc970038 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@
软件变化请查看:[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)
软件下载请转到:[发布页面](https://github.com/lyswhut/lx-music-desktop/releases)
-或者到网盘下载:`https://www.lanzous.com/b906260/` 密码:`glqw`
+或者到网盘下载(网盘内有MAC、windows版):`https://www.lanzous.com/b906260/` 密码:`glqw`
歌曲默认下载到桌面,可自行到设置页面更改。
若排行榜上的某些歌曲**无法播放**,可尝试**直接搜索**该歌曲后播放。
diff --git a/package-lock.json b/package-lock.json
index 9ec31398..6b16ef48 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "lx-music-desktop",
- "version": "0.2.4",
+ "version": "0.3.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -4229,6 +4229,11 @@
"randomfill": "^1.0.3"
}
},
+ "crypto-js": {
+ "version": "3.1.9-1",
+ "resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-3.1.9-1.tgz",
+ "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg="
+ },
"crypto-random-string": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/crypto-random-string/download/crypto-random-string-1.0.0.tgz",
diff --git a/package.json b/package.json
index 3fcb89f9..882a7556 100644
--- a/package.json
+++ b/package.json
@@ -195,6 +195,7 @@
},
"dependencies": {
"axios": "^0.19.0",
+ "crypto-js": "^3.1.9-1",
"electron-log": "^3.0.7",
"electron-store": "^4.0.0",
"electron-updater": "^4.1.2",
diff --git a/publish/changeLog.md b/publish/changeLog.md
index b90f87c0..eb2dc4d3 100644
--- a/publish/changeLog.md
+++ b/publish/changeLog.md
@@ -1,5 +1,7 @@
### 修复
+- **messoer**的接口已经关闭,暂时切换到临时接口使用,部分功能受限。。。
- 修复设置界面更新出错时仍然显示更新下载中的问题
- 修复手动定位播放进度条时存在偏差的问题
- 屏蔽播放器中没有歌曲时对进度条的点击
+
diff --git a/src/renderer/components/core/Aside.vue b/src/renderer/components/core/Aside.vue
index 50e1bf9c..9d4e8c3b 100644
--- a/src/renderer/components/core/Aside.vue
+++ b/src/renderer/components/core/Aside.vue
@@ -9,10 +9,10 @@ div(:class="$style.aside")
dt 在线音乐
dd
router-link(:active-class="$style.active" to="search") 搜索
+ //- dd
+ router-link(:active-class="$style.active" to="songList") 歌单
dd
router-link(:active-class="$style.active" to="leaderboard") 排行榜
- //- dd
- router-link(:active-class="$style.active" to="recommend") 歌单
dl
dt 我的音乐
dd
diff --git a/src/renderer/route/paths.js b/src/renderer/route/paths.js
index 42e1b7ac..a211fd06 100644
--- a/src/renderer/route/paths.js
+++ b/src/renderer/route/paths.js
@@ -18,9 +18,9 @@ export default [
view: 'Leaderboard',
},
{
- path: '/recommend',
- name: 'recommend',
- view: 'Recommend',
+ path: '/songList',
+ name: 'songList',
+ view: 'SongList',
},
{
path: '/list',
diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js
index 633a4d95..f9e0daa8 100644
--- a/src/renderer/utils/index.js
+++ b/src/renderer/utils/index.js
@@ -2,6 +2,7 @@ import fs from 'fs'
import { shell, remote } from 'electron'
import path from 'path'
import os from 'os'
+import crypto from 'crypto'
/**
* 获取两个数之间的随机整数,大于等于min,小于max
@@ -184,7 +185,7 @@ export const updateSetting = setting => {
},
themeId: 0,
sourceId: 'kw',
- apiSource: 'messoer',
+ apiSource: 'temp',
randomAnimate: true,
ignoreVersion: null,
}
@@ -201,7 +202,7 @@ export const updateSetting = setting => {
objectDeepMerge(defaultSetting, overwriteSetting)
setting = defaultSetting
}
- setting.apiSource = 'messoer' // 强制设置回 messoer 接口源
+ if (setting.apiSource == 'messoer') setting.apiSource = 'temp' // 强制设置回 temp 接口源
return setting
}
@@ -220,3 +221,10 @@ let dom_title = document.getElementsByTagName('title')[0]
export const setTitle = title => {
dom_title.innerText = title || '洛雪音乐助手'
}
+
+
+/**
+ * 创建 MD5 hash
+ * @param {*} str
+ */
+export const toMD5 = str => crypto.createHash('md5').update(str).digest('hex')
diff --git a/src/renderer/utils/message.js b/src/renderer/utils/message.js
index d48883fd..c58656e5 100644
--- a/src/renderer/utils/message.js
+++ b/src/renderer/utils/message.js
@@ -2,6 +2,6 @@ export const requestMsg = {
fail: '请求异常😮,可以多试几次,若还是不行就换一首吧。。。',
unachievable: '哦No😱...接口无法访问了!',
// unachievable: '哦No😱...接口无法访问了!已帮你切换到临时接口,重试下看能不能播放吧~',
- notConnectNetwork: '无法连接网络',
+ notConnectNetwork: '无法连接到服务器',
cancelRequest: '取消http请求',
}
diff --git a/src/renderer/utils/music/api-source.js b/src/renderer/utils/music/api-source.js
index c293e3f7..0a41cdcd 100644
--- a/src/renderer/utils/music/api-source.js
+++ b/src/renderer/utils/music/api-source.js
@@ -1,24 +1,36 @@
-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'
+// import kw_api_messoer from './kw/api-messoer'
+// 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'
+import kw_api_internal from './kw/api-internal'
+import tx_api_internal from './tx/api-internal'
+import kg_api_internal from './kg/api-internal'
+import wy_api_internal from './wy/api-internal'
+import bd_api_internal from './bd/api-internal'
const apis = {
- kw_api_messoer,
- tx_api_messoer,
- kg_api_messoer,
- wy_api_messoer,
- bd_api_messoer,
+ // kw_api_messoer,
+ // tx_api_messoer,
+ // kg_api_messoer,
+ // wy_api_messoer,
+ // bd_api_messoer,
+ kw_api_internal,
+ tx_api_internal,
+ kg_api_internal,
+ wy_api_internal,
+ bd_api_internal,
kw_api_temp,
}
const getAPI = source => {
switch (window.globalObj.apiSource) {
- case 'messoer':
- return apis[`${source}_api_messoer`]
+ // case 'messoer':
+ // return apis[`${source}_api_messoer`]
+ case 'internal':
+ return apis[`${source}_api_internal`]
case 'temp':
return apis[`${source}_api_temp`]
}
diff --git a/src/renderer/utils/music/bd/api-internal.js b/src/renderer/utils/music/bd/api-internal.js
new file mode 100644
index 00000000..9ecc51b8
--- /dev/null
+++ b/src/renderer/utils/music/bd/api-internal.js
@@ -0,0 +1,44 @@
+import { httpFatch } from '../../request'
+import { requestMsg } from '../../message'
+
+const api_internal = {
+ successCode: 2200,
+ // getMusicUrl(songInfo, type) {
+ // const requestObj = httpFatch(`http://play.taihe.com/data/music/songlink`, {
+ // method: 'post',
+ // headers: {
+ // Origin: 'http://play.taihe.com',
+ // },
+ // formData: {
+ // songIds: songInfo.songmid,
+ // },
+ // })
+ // requestObj.promise = requestObj.promise.then(({ body }) => {
+ // console.log(body)
+ // return Promise.reject()
+ // // if (body.error_code !== this.successCode) return this.getMusicUrl(songInfo, type)
+ // // return body.code === 200 ? Promise.resolve({ type, url: body.result.bitrate.file_link }) : Promise.reject(new Error(requestMsg.fail))
+ // })
+ // return requestObj
+ // },
+ getMusicInfo(songInfo, tryNum = 0) {
+ const requestObj = httpFatch(`http://tingapi.ting.baidu.com/v1/restserver/ting?from=webapp_music&method=baidu.ting.song.baseInfos&song_id=${songInfo.songmid}`)
+ requestObj.promise = requestObj.promise.then(({ body }) => {
+ if (body.error_code !== this.successCode) return tryNum > 5 ? Promise.reject(new Error(requestMsg.fail)) : this.getMusicInfo(songInfo, ++tryNum)
+ return body ? Promise.resolve(body.result.items[0]) : Promise.reject(new Error(requestMsg.fail))
+ })
+ return requestObj
+ },
+ getPic(songInfo) {
+ const requestObj = this.getMusicInfo(songInfo)
+ requestObj.promise = requestObj.promise.then(info => info.pic_premium)
+ return requestObj
+ },
+ getLyric(songInfo) {
+ const requestObj = this.getMusicInfo(songInfo)
+ requestObj.promise.then(info => httpFatch(info.lrclink).promise)
+ return requestObj
+ },
+}
+
+export default api_internal
diff --git a/src/renderer/utils/music/bd/api-messoer.js b/src/renderer/utils/music/bd/api-messoer.js
index 72e267bd..80609c8b 100644
--- a/src/renderer/utils/music/bd/api-messoer.js
+++ b/src/renderer/utils/music/bd/api-messoer.js
@@ -1,11 +1,13 @@
import { httpFatch } from '../../request'
import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
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,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
@@ -15,7 +17,8 @@ const api_messoer = {
getPic(songInfo, size = '500') {
const requestObj = httpFatch(`https://v1.itooi.cn/baidu/pic?id=${songInfo.songmid}&imageSize=${size}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
@@ -25,7 +28,8 @@ const api_messoer = {
getLyric(songInfo) {
const requestObj = httpFatch(`https://v1.itooi.cn/baidu/lrc?id=${songInfo.songmid}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
diff --git a/src/renderer/utils/music/bd/songList.js b/src/renderer/utils/music/bd/songList.js
index 8aa98c50..ff5593cd 100644
--- a/src/renderer/utils/music/bd/songList.js
+++ b/src/renderer/utils/music/bd/songList.js
@@ -4,9 +4,9 @@ import CryptoJS from 'crypto-js'
export default {
_requestObj_tags: null,
- _requestObj_songList: null,
- _requestObj_songListRecommend: null,
- _requestObj_songListDetail: null,
+ _requestObj_list: null,
+ _requestObj_listRecommend: null,
+ _requestObj_listDetail: null,
limit_list: 20,
limit_song: 25,
successCode: 22000,
@@ -87,7 +87,7 @@ export default {
version: '10.1.8',
}, 'baidu.ting.ugcdiy.getChannels')
},
- getSongListUrl(sortType, tagName, page) {
+ getListUrl(sortType, tagName, page) {
return this.createUrl({
channelname: tagName,
from: 'qianqianmini',
@@ -139,14 +139,14 @@ export default {
// 获取列表数据
getList(sortId, tagId, page) {
- if (this._requestObj_songList) this._requestObj_songList.cancelHttp()
- this._requestObj_songList = httpFatch(
- this.getSongListUrl(sortId, tagId, page)
+ if (this._requestObj_list) this._requestObj_list.cancelHttp()
+ this._requestObj_list = httpFatch(
+ this.getListUrl(sortId, tagId, page)
)
- return this._requestObj_songList.promise.then(({ body }) => {
+ return this._requestObj_list.promise.then(({ body }) => {
if (body.error_code !== this.successCode) return this.getSongList(sortId, tagId, page)
return {
- list: this.filterSongList(body.diyInfo),
+ list: this.filterList(body.diyInfo),
total: body.nums,
page,
limit: this.limit_list,
@@ -164,7 +164,7 @@ export default {
if (num > 10000) return parseInt(num / 1000) / 10 + '万'
return num
},
- filterSongList(rawData) {
+ filterList(rawData) {
return rawData.map(item => ({
play_count: this.formatPlayCount(item.listen_num),
id: item.list_id,
@@ -179,11 +179,11 @@ export default {
// 获取歌曲列表内的音乐
getListDetail(id, page) {
- if (this._requestObj_songListDetail) {
- this._requestObj_songListDetail.cancelHttp()
+ if (this._requestObj_listDetail) {
+ this._requestObj_listDetail.cancelHttp()
}
- this._requestObj_songListDetail = httpFatch(this.getListDetailUrl(id, page))
- return this._requestObj_songListDetail.promise.then(({ body }) => {
+ this._requestObj_listDetail = httpFatch(this.getListDetailUrl(id, page))
+ return this._requestObj_listDetail.promise.then(({ body }) => {
if (body.error_code !== this.successCode) return this.getListDetail(id, page)
let listData = this.filterData(body.result.songlist)
return {
diff --git a/src/renderer/utils/music/kg/api-internal.js b/src/renderer/utils/music/kg/api-internal.js
new file mode 100644
index 00000000..2fe074c7
--- /dev/null
+++ b/src/renderer/utils/music/kg/api-internal.js
@@ -0,0 +1,41 @@
+import { httpFatch } from '../../request'
+import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
+
+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,
+ headers,
+ })
+ 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,
+ headers,
+ })
+ 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,
+ headers,
+ })
+ 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/api-messoer.js b/src/renderer/utils/music/kg/api-messoer.js
index 017959af..2fe074c7 100644
--- a/src/renderer/utils/music/kg/api-messoer.js
+++ b/src/renderer/utils/music/kg/api-messoer.js
@@ -1,11 +1,13 @@
import { httpFatch } from '../../request'
import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
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,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
@@ -15,7 +17,8 @@ const api_messoer = {
getPic(songInfo) {
const requestObj = httpFatch(`https://v1.itooi.cn/kugou/pic?id=${songInfo.hash}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
@@ -25,7 +28,8 @@ const api_messoer = {
getLyric(songInfo) {
const requestObj = httpFatch(`https://v1.itooi.cn/kugou/lrc?id=${songInfo.hash}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
diff --git a/src/renderer/utils/music/kg/songList.js b/src/renderer/utils/music/kg/songList.js
index 9f6d4d12..82b23606 100644
--- a/src/renderer/utils/music/kg/songList.js
+++ b/src/renderer/utils/music/kg/songList.js
@@ -3,8 +3,8 @@ import { formatPlayTime, sizeFormate } from '../../index'
export default {
_requestObj_tagInfo: null,
- _requestObj_songList: null,
- _requestObj_songListDetail: null,
+ _requestObj_list: null,
+ _requestObj_listDetail: null,
currentTagInfo: {
id: null,
info: null,
@@ -90,18 +90,18 @@ export default {
},
getSongList(sortId, tagId, page) {
- if (this._requestObj_songList) this._requestObj_songList.cancelHttp()
- this._requestObj_songList = httpFatch(
+ if (this._requestObj_list) this._requestObj_list.cancelHttp()
+ this._requestObj_list = httpFatch(
this.getSongListUrl(sortId, tagId, page)
)
- return this._requestObj_songList.promise.then(({ body }) => {
+ return this._requestObj_list.promise.then(({ body }) => {
if (body.status !== 1) return this.getSongList(sortId, tagId, page)
- return this.filterSongList(body.data)
+ return this.filterList(body.data)
})
},
getSongListRecommend() {
- if (this._requestObj_songListRecommend) this._requestObj_songListRecommend.cancelHttp()
- this._requestObj_songListRecommendRecommend = httpFatch(
+ if (this._requestObj_listRecommend) this._requestObj_listRecommend.cancelHttp()
+ this._requestObj_listRecommendRecommend = httpFatch(
'http://everydayrec.service.kugou.com/guess_special_recommend',
{
method: 'post',
@@ -121,12 +121,12 @@ export default {
},
}
)
- return this._requestObj_songListRecommend.promise.then(({ body }) => {
+ return this._requestObj_listRecommend.promise.then(({ body }) => {
if (body.status !== 1) return this.getSongListRecommend()
- return this.filterSongList(body.data)
+ return this.filterList(body.data)
})
},
- filterSongList(rawData) {
+ filterList(rawData) {
return rawData.map(item => ({
play_count: item.total_play_count,
id: item.specialid,
@@ -140,9 +140,9 @@ export default {
},
getListDetail(id, page) { // 获取歌曲列表内的音乐
- if (this._requestObj_songListDetail) this._requestObj_songListDetail.cancelHttp()
- this._requestObj_songListDetail = httpFatch(this.getSongListDetailUrl(id))
- return this._requestObj_songListDetail.promise.then(({ body }) => {
+ if (this._requestObj_listDetail) this._requestObj_listDetail.cancelHttp()
+ this._requestObj_listDetail = httpFatch(this.getSongListDetailUrl(id))
+ return this._requestObj_listDetail.promise.then(({ body }) => {
let listData = body.match(this.regExps.listData)
if (listData) listData = this.filterData(JSON.parse(RegExp.$1))
return {
diff --git a/src/renderer/utils/music/kw/api-internal.js b/src/renderer/utils/music/kw/api-internal.js
new file mode 100644
index 00000000..6b22eb59
--- /dev/null
+++ b/src/renderer/utils/music/kw/api-internal.js
@@ -0,0 +1,30 @@
+import { httpFatch } from '../../request'
+import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
+
+const api_messoer = {
+ getMusicUrl(songInfo, type) {
+ const requestObj = httpFatch(`https://v1.itooi.cn/kuwo/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
+ method: 'get',
+ timeout,
+ headers,
+ })
+ 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/kuwo/pic?id=${songInfo.songmid}&isRedirect=0`, {
+ method: 'get',
+ timeout,
+ headers,
+ })
+ requestObj.promise = requestObj.promise.then(({ body }) => {
+ return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
+ })
+ return requestObj
+ },
+}
+
+export default api_messoer
diff --git a/src/renderer/utils/music/kw/api-messoer.js b/src/renderer/utils/music/kw/api-messoer.js
index 599c14ab..6b22eb59 100644
--- a/src/renderer/utils/music/kw/api-messoer.js
+++ b/src/renderer/utils/music/kw/api-messoer.js
@@ -1,11 +1,13 @@
import { httpFatch } from '../../request'
import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
const api_messoer = {
getMusicUrl(songInfo, type) {
const requestObj = httpFatch(`https://v1.itooi.cn/kuwo/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
@@ -15,7 +17,8 @@ const api_messoer = {
getPic(songInfo) {
const requestObj = httpFatch(`https://v1.itooi.cn/kuwo/pic?id=${songInfo.songmid}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
diff --git a/src/renderer/utils/music/kw/api-temp.js b/src/renderer/utils/music/kw/api-temp.js
index 0c8436f2..14ac6d9a 100644
--- a/src/renderer/utils/music/kw/api-temp.js
+++ b/src/renderer/utils/music/kw/api-temp.js
@@ -2,7 +2,7 @@ import { httpFatch } from '../../request'
const api_temp = {
getMusicUrl(songInfo, type) {
- const requestObj = httpFatch(`https://www.stsky.cn/api/temp/getMusicUrl.php?id=${songInfo.songmid}&type=${type}`, {
+ const requestObj = httpFatch(`http://45.32.53.128:3002/m/kw/u/${songInfo.songmid}/${type}`, {
method: 'get',
})
requestObj.promise = requestObj.promise.then(({ body }) => {
@@ -11,7 +11,7 @@ const api_temp = {
return requestObj
},
getPic(songInfo) {
- const requestObj = httpFatch(`https://www.stsky.cn/api/temp/getPic.php?size=320&songmid=${songInfo.songmid}`, {
+ const requestObj = httpFatch(`http://45.32.53.128:3002/m/kw/i/${songInfo.songmid}`, {
method: 'get',
})
requestObj.promise = requestObj.promise.then(({ body }) => {
diff --git a/src/renderer/utils/music/kw/leaderboard.js b/src/renderer/utils/music/kw/leaderboard.js
index 2146eb66..95a97e09 100644
--- a/src/renderer/utils/music/kw/leaderboard.js
+++ b/src/renderer/utils/music/kw/leaderboard.js
@@ -1,5 +1,7 @@
import { httpGet, cancelHttp } from '../../request'
-import { formatPlayTime } from '../../index'
+import { formatPlayTime, decodeName } from '../../index'
+import { formatSinger } from './util'
+
export default {
list: [
@@ -143,9 +145,9 @@ export default {
}
// types.reverse()
return {
- singer: item.artist,
- name: item.name,
- albumName: item.album,
+ singer: formatSinger(decodeName(item.artist)),
+ name: decodeName(item.name),
+ albumName: decodeName(item.album),
albumId: item.albumid,
songmid: item.id,
source: 'kw',
diff --git a/src/renderer/utils/music/kw/songList.js b/src/renderer/utils/music/kw/songList.js
new file mode 100644
index 00000000..2a0ea23a
--- /dev/null
+++ b/src/renderer/utils/music/kw/songList.js
@@ -0,0 +1,173 @@
+import { httpFatch } from '../../request'
+import { formatPlayTime, decodeName } from '../../index'
+import { formatSinger } from './util'
+
+export default {
+ _requestObj_tags: null,
+ _requestObj_hotTags: null,
+ _requestObj_list: null,
+ _requestObj_listDetail: null,
+ limit_list: 100,
+ limit_song: 25,
+ successCode: 200,
+ sortList: [
+ {
+ name: '最热',
+ id: 'hot',
+ },
+ {
+ name: '最新',
+ id: 'new',
+ },
+ ],
+ tagsUrl: 'http://wapi.kuwo.cn/api/pc/classify/playlist/getTagList?cmd=rcm_keyword_playlist&user=0&prod=kwplayer_pc_9.0.5.0&vipver=9.0.5.0&source=kwplayer_pc_9.0.5.0&loginUid=0&loginSid=0&appUid=76039576',
+ hotTagUrl: 'http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmTagList?loginUid=0&loginSid=0&appUid=76039576',
+ getListUrl({ sortType, id, page }) {
+ return id
+ ? `http://wapi.kuwo.cn/api/pc/classify/playlist/getTagPlayList?loginUid=0&loginSid=0&appUid=76039576&id=${id}&pn=${page}&rn=${this.limit}`
+ : `http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmPlayList?loginUid=0&loginSid=0&appUid=76039576&pn=${page}&rn=${this.limit}&order=${sortType}`
+ },
+ getListDetailUrl(id, page) {
+ return `http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=${id}&pn=${page - 1}&rn=${this.limit}&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1`
+ },
+
+
+ // 获取标签
+ getTags() {
+ if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
+ this._requestObj_tags = httpFatch(this.tagsUrl)
+ return this._requestObj_tags.promise.then(({ body }) => {
+ if (body.code !== this.successCode) return this.getTags()
+ return this.filterTagInfo(body.data.tags)
+ })
+ },
+ // 获取标签
+ getHotTags() {
+ if (this._requestObj_hotTags) this._requestObj_hotTags.cancelHttp()
+ this._requestObj_hotTags = httpFatch(this.hotTagUrl)
+ return this._requestObj_hotTags.promise.then(({ body }) => {
+ if (body.code !== this.successCode) return this.getHotTags()
+ return this.filterInfoHotTag(body.data.data)
+ })
+ },
+ filterInfoHotTag(rawList) {
+ return rawList.map(item => ({
+ id: item.id,
+ name: item.name,
+ }))
+ },
+ filterTagInfo(rawList) {
+ return rawList.map(type => ({
+ type: type.name,
+ list: type.data.map(item => ({
+ parent_id: type.id,
+ parent_name: type.name,
+ id: item.id,
+ name: item.name,
+ })),
+ }))
+ },
+
+ // 获取列表数据
+ getList(sortId, tagId, page) {
+ if (this._requestObj_list) this._requestObj_list.cancelHttp()
+ this._requestObj_list = httpFatch(
+ this.getListUrl({ sortId, id: tagId, page })
+ )
+ return this._requestObj_list.promise.then(({ body }) => {
+ if (body.code !== this.successCode) return this.getList({ sortId, id: tagId, page })
+ return {
+ list: this.filterList(body.data.data),
+ total: body.data.total,
+ page: body.data.pn,
+ limit: body.data.rn,
+ }
+ })
+ },
+
+
+ /**
+ * 格式化播放数量
+ * @param {*} num
+ */
+ formatPlayCount(num) {
+ if (num > 100000000) return parseInt(num / 10000000) / 10 + '亿'
+ if (num > 10000) return parseInt(num / 1000) / 10 + '万'
+ return num
+ },
+ filterList(rawData) {
+ return rawData.map(item => ({
+ play_count: this.formatPlayCount(item.listencnt),
+ id: item.id,
+ author: item.uname,
+ name: item.name,
+ // time: item.publish_time,
+ img: item.img,
+ grade: item.favorcnt / 10,
+ desc: item.desc,
+ }))
+ },
+
+ // 获取歌曲列表内的音乐
+ getListDetail(id, page) {
+ if (this._requestObj_listDetail) {
+ this._requestObj_listDetail.cancelHttp()
+ }
+ this._requestObj_listDetail = httpFatch(this.getListDetailUrl(id, page))
+ return this._requestObj_listDetail.promise.then(({ body }) => {
+ if (body.result !== 'ok') return this.getListDetail(id, page)
+ return {
+ list: this.filterListDetail(body.data.musiclist),
+ page,
+ limit: body.rn,
+ total: body.total,
+ }
+ })
+ },
+ filterListDetail(rawData) {
+ // console.log(rawList)
+ return rawData.map((item, inedx) => {
+ let formats = item.formats.split('|')
+ let types = []
+ let _types = {}
+ if (formats.indexOf('MP3128')) {
+ types.push({ type: '128k', size: null })
+ _types['128k'] = {
+ size: null,
+ }
+ }
+ if (formats.indexOf('MP3H')) {
+ types.push({ type: '320k', size: null })
+ _types['320k'] = {
+ size: null,
+ }
+ }
+ if (formats.indexOf('ALFLAC')) {
+ types.push({ type: 'flac', size: null })
+ _types['flac'] = {
+ size: null,
+ }
+ }
+
+ return {
+ singer: formatSinger(decodeName(item.artist)),
+ name: decodeName(item.name),
+ albumName: decodeName(item.album),
+ albumId: item.albumid,
+ songmid: item.id,
+ source: 'kw',
+ interval: formatPlayTime(parseInt(item.duration)),
+ img: null,
+ lrc: null,
+ types,
+ _types,
+ typeUrl: {},
+ }
+ })
+ },
+
+}
+
+// getList
+// getTags
+// getListDetail
diff --git a/src/renderer/utils/music/messoer.js b/src/renderer/utils/music/messoer.js
new file mode 100644
index 00000000..936b2964
--- /dev/null
+++ b/src/renderer/utils/music/messoer.js
@@ -0,0 +1,9 @@
+export const bHh = '624868746c'
+
+export const headers = {
+ 'User-Agent': 'lx-music request',
+ [bHh]: [bHh],
+}
+
+
+export const timeout = 10000
diff --git a/src/renderer/utils/music/tx/api-internal.js b/src/renderer/utils/music/tx/api-internal.js
new file mode 100644
index 00000000..06c7536f
--- /dev/null
+++ b/src/renderer/utils/music/tx/api-internal.js
@@ -0,0 +1,24 @@
+import { httpFatch } from '../../request'
+import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
+
+const api_messoer = {
+ getMusicUrl(songInfo, type) {
+ const requestObj = httpFatch(`https://v1.itooi.cn/tencent/url?id=${songInfo.strMediaMid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
+ method: 'get',
+ timeout,
+ headers,
+ })
+ 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) {
+ return {
+ promise: Promise.resolve(`https://y.gtimg.cn/music/photo_new/T002R500x500M000${songInfo.albumId}.jpg`),
+ }
+ },
+}
+
+export default api_messoer
diff --git a/src/renderer/utils/music/tx/api-messoer.js b/src/renderer/utils/music/tx/api-messoer.js
index 49ac2f04..06c7536f 100644
--- a/src/renderer/utils/music/tx/api-messoer.js
+++ b/src/renderer/utils/music/tx/api-messoer.js
@@ -1,11 +1,13 @@
import { httpFatch } from '../../request'
import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
const api_messoer = {
getMusicUrl(songInfo, type) {
const requestObj = httpFatch(`https://v1.itooi.cn/tencent/url?id=${songInfo.strMediaMid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
diff --git a/src/renderer/utils/music/wy/api-internal.js b/src/renderer/utils/music/wy/api-internal.js
new file mode 100644
index 00000000..272cc26d
--- /dev/null
+++ b/src/renderer/utils/music/wy/api-internal.js
@@ -0,0 +1,41 @@
+import { httpFatch } from '../../request'
+import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
+
+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,
+ headers,
+ })
+ 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,
+ headers,
+ })
+ 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,
+ headers,
+ })
+ 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/api-messoer.js b/src/renderer/utils/music/wy/api-messoer.js
index 2d8db5f0..272cc26d 100644
--- a/src/renderer/utils/music/wy/api-messoer.js
+++ b/src/renderer/utils/music/wy/api-messoer.js
@@ -1,11 +1,13 @@
import { httpFatch } from '../../request'
import { requestMsg } from '../../message'
+import { headers, timeout } from '../messoer'
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,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
@@ -15,7 +17,8 @@ const api_messoer = {
getPic(songInfo) {
const requestObj = httpFatch(`https://v1.itooi.cn/netease/pic?id=${songInfo.songmid}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
@@ -25,7 +28,8 @@ const api_messoer = {
getLyric(songInfo) {
const requestObj = httpFatch(`https://v1.itooi.cn/netease/lrc?id=${songInfo.songmid}&isRedirect=0`, {
method: 'get',
- timeout: 5000,
+ timeout,
+ headers,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
diff --git a/src/renderer/utils/request.js b/src/renderer/utils/request.js
index 85d1ef4e..ec34f11a 100644
--- a/src/renderer/utils/request.js
+++ b/src/renderer/utils/request.js
@@ -2,28 +2,11 @@ import request from 'request'
// import progress from 'request-progress'
import { debugRequest } from './env'
import { requestMsg } from './message'
+import { bHh } from './music/messoer'
// import fs from 'fs'
const headers = {
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
-}
-
-const fatchData = (url, method, options, callback) => {
- // console.log(url, options)
- console.log('---start---', url)
- return request(url, {
- method,
- headers: Object.assign({}, headers, options.headers || {}),
- Origin: options.origin,
- data: options.data,
- timeout: options.timeout || 10000,
- json: options.format === undefined || options.format === 'json',
- }, (err, resp, body) => {
- if (err) return callback(err, null)
-
- // console.log('---end---', url)
- callback(null, resp, body)
- })
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
}
/**
@@ -231,3 +214,26 @@ export const http_jsonp = (url, options, callback) => {
callback(err, resp, body)
})
}
+
+const fatchData = (url, method, options, callback) => {
+ // console.log(url, options)
+ console.log('---start---', url)
+ if (options.headers && options.headers[bHh]) {
+ let s = Buffer.from(bHh, 'hex').toString()
+ s = s.replace(s.substr(-1), '')
+ s = Buffer.from(s, 'base64').toString()
+ options.headers[s] = !!s
+ delete options.headers[bHh]
+ }
+ return request(url, {
+ method,
+ headers: Object.assign({}, headers, options.headers || {}),
+ Origin: options.origin,
+ data: options.data,
+ timeout: options.timeout || 10000,
+ json: options.format === undefined || options.format === 'json',
+ }, (err, resp, body) => {
+ if (err) return callback(err, null)
+ callback(null, resp, body)
+ })
+}
diff --git a/src/renderer/views/Setting.vue b/src/renderer/views/Setting.vue
index e8496fbd..ff078eef 100644
--- a/src/renderer/views/Setting.vue
+++ b/src/renderer/views/Setting.vue
@@ -74,7 +74,7 @@ div.scroll(:class="$style.setting")
p.small 当前版本:{{version.version}}
p.small(v-if="version.newVersion")
span(v-if="isLatestVer") 软件已是最新,尽情地体验吧~🥂
- material-btn(v-else-if="setting.ignoreVersion || version.isError" :class="[$style.btn, $style.gapLeft]" min @click="showUpdateModal") 打开更新窗口
+ material-btn(v-else-if="setting.ignoreVersion || version.isError" :class="[$style.btn, $style.gapLeft]" min @click="showUpdateModal") 打开更新窗口 🚀
span(v-else) 发现新版本并在努力下载中,请稍等...⏳
p.small(v-else) 检查更新中...
dt 关于洛雪音乐
@@ -164,14 +164,19 @@ export default {
apiSources: [
{
id: 'messoer',
- label: '由 messoer 提供的接口(推荐,软件的所有功能都可用)',
- disabled: false,
+ // label: '由 messoer 提供的接口(推荐,软件的所有功能都可用)',
+ label: '由 messoer 提供的接口(该接口已关闭)',
+ disabled: true,
},
+ // {
+ // id: 'internal',
+ // label: '内置接口(只能试听或下载128k音质,该接口支持软件的所有功能)',
+ // disabled: false,
+ // },
{
id: 'temp',
- // label: '临时接口(软件的某些功能将不可用,建议在messoer不可用时再切换到本选项)',
- label: '临时接口(因服务器被攻击,本接口已关闭)',
- disabled: true,
+ label: '临时接口(软件的某些功能将不可用,但可下载无损等音质)',
+ disabled: false,
},
],
musicNames: [
diff --git a/src/renderer/views/Recommend.vue b/src/renderer/views/SongList.vue
similarity index 90%
rename from src/renderer/views/Recommend.vue
rename to src/renderer/views/SongList.vue
index 16b5e2bd..6c2e9d97 100644
--- a/src/renderer/views/Recommend.vue
+++ b/src/renderer/views/SongList.vue
@@ -5,7 +5,7 @@