diff --git a/package.json b/package.json index 43a763e..81bc7c9 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build-main": "cross-env NODE_ENV=production node -r babel-register ./node_modules/webpack/bin/webpack --config ./config/webpack.config.electron.js --progress --profile --colors", "build-renderer": "cross-env NODE_ENV=production node -r babel-register ./node_modules/webpack/bin/webpack --config ./config/webpack.config.production.js --progress --profile --colors", "build": "rm -rf dist && npm run build-main && npm run build-renderer", - "api": "cross-env NODE_ENV=development AUTORUN=1 DEBUG_COLORS=true DEBUG=dev:*,-not_this node -r babel-register server/api.js", + "api": "cross-env NODE_ENV=development APIONLY=1 DEBUG_COLORS=true DEBUG=dev:*,-not_this node -r babel-register server/api.js", "hot-server": "cross-env NODE_ENV=development DEBUG_COLORS=true DEBUG=dev:*,-not_this node -r babel-register server/dev.js", "start-hot": "cross-env HOT=1 NODE_ENV=development DEBUG_COLORS=true DEBUG=dev:*,-not_this ./node_modules/.bin/electron -r babel-register -r babel-polyfill ./main", "package-mac": "npm run build && rm -rf release && build --mac --projectDir ./dist", diff --git a/server/api.js b/server/api.js index ac1cf73..be22910 100644 --- a/server/api.js +++ b/server/api.js @@ -254,7 +254,7 @@ app.use('/api/search', require('./router/search')); app.use('/api/comments', require('./router/comments')); app.use('/api/lyrics', cache('360 minutes'), require('./router/lyrics')); -if (process.env.AUTORUN) { +if (process.env.APIONLY) { console.log(`API Server run with port: ${port}`); app.listen(port); } diff --git a/server/router/player.js b/server/router/player.js index a412b82..ff3c1b8 100644 --- a/server/router/player.js +++ b/server/router/player.js @@ -5,7 +5,6 @@ import apicache from 'apicache' import axios from 'axios'; import _debug from 'debug'; import chalk from 'chalk'; -import search from '../search'; /* eslint-enable */ const debug = _debug('dev:api'); @@ -260,9 +259,11 @@ router.get('/song/:id/:name/:artists/:flac?', cache('3 minutes', onlyStatus200), } } catch (ex) { try { - // Search from other source - debug(chalk.underline.black.bgYellow(`πŸ”Ž ${name} - ${artists}`)); - song = await search(name, artists); + if (!process.env.APIONLY) { + // Search from other source + debug(chalk.underline.black.bgYellow(`πŸ”Ž ${name} - ${artists}`)); + song = await require('../search').default(name, artists); + } } catch (ex) { debug(chalk.red.underline.bold(`πŸ’” Not found: "${name} - ${artists}"`)); } diff --git a/server/search/Baidu.js b/server/search/Baidu.js index 748aa05..ddff66b 100644 --- a/server/search/Baidu.js +++ b/server/search/Baidu.js @@ -42,9 +42,10 @@ export default async(request, keyword, artists) => { return Promise.reject(); } - song = { - src: response.data.songList[0].songLink, - }; + song = response.data.songList[0]; + + song.src = song.songLink; + song.bitRate = song.rate * 1000; if (!song.src) { return Promise.reject(); diff --git a/server/search/Kugou.js b/server/search/Kugou.js index 8b2e9da..7f064c0 100644 --- a/server/search/Kugou.js +++ b/server/search/Kugou.js @@ -65,9 +65,8 @@ export default async(request, keyword, artists) => { let song = await getURL(e['320hash'] || e['hash']); if (song) { - return { - src: song.url - }; + song.src = song.url; + return song; } } } catch (ex) { diff --git a/server/search/Kuwo.js b/server/search/Kuwo.js new file mode 100644 index 0000000..50c3f5f --- /dev/null +++ b/server/search/Kuwo.js @@ -0,0 +1,77 @@ + +import _debug from 'debug'; +import chalk from 'chalk'; + +const debug = _debug('dev:plugin:Kuwo'); +const error = _debug('dev:plugin:Kuwo:error'); + +export default async(request, keyword, artists) => { + debug(chalk.black.bgGreen('πŸ’Š Loaded Kuwo music.')); + + try { + // Apply cookie + await request({ + uri: 'http://www.kuwo.cn/', + method: 'HEAD', + }); + + var response = await request({ + uri: 'http://search.kuwo.cn/r.s', + qs: { + ft: 'music', + itemset: 'web_2013', + client: 'kt', + rformat: 'json', + encoding: 'utf8', + all: [keyword].concat(artists.split(',')).join('+'), + pn: 0, + rn: 20, + }, + }); + // eslint-disable-next-line + response = eval('(' + response + ')'); + artists = artists.split(','); + + var songs = response.abslist || []; + var payload = songs.find( + e => artists.findIndex(artist => e.ARTIST.indexOf(artist) !== -1) > -1 + ); + + console.log(payload); + + if (!payload) { + error(chalk.black.bgRed('🚧 Nothing.')); + return Promise.reject(); + } + + response = await request({ + uri: 'http://antiserver.kuwo.cn/anti.s', + qs: { + type: 'convert_url', + format: 'aac|mp3|wma', + response: 'url', + rid: payload.MP3RID, + }, + }); + + if (!response) { + error(chalk.black.bgRed('🚧 Nothing.')); + return Promise.reject(); + } + + var song = { + src: response, + isFlac: response.endsWith('.aac') + }; + + debug(chalk.black.bgGreen('🚚 Result >>>')); + debug(song); + debug(chalk.black.bgGreen('🚚 <<<')); + } catch (ex) { + // Anti-warnning + error('Failed to get song: %O', ex); + return Promise.reject(); + } + + return song; +}; diff --git a/server/search/MiGu.js b/server/search/MiGu.js index 3aeb493..0479098 100644 --- a/server/search/MiGu.js +++ b/server/search/MiGu.js @@ -34,9 +34,7 @@ export default async(request, keyword, artists) => { debug(e); debug(chalk.black.bgGreen('🚚 <<<')); - return { - src: e.mp3 - }; + return Object.assign({}, e, { src: e.mp3 }); } } } catch (ex) { diff --git a/server/search/QQ.js b/server/search/QQ.js index 1173f20..5ddc52e 100644 --- a/server/search/QQ.js +++ b/server/search/QQ.js @@ -51,12 +51,14 @@ async function getSong(mid) { if (file.size_320mp3) { return { + bitRate: 320000, src: getURL(`M800${mid}.mp3`, key, guid), }; } if (file.size_128mp3) { return { + bitRate: 128000, src: getURL(`M500${mid}.mp3`, key, guid), }; } diff --git a/server/search/Xiami.js b/server/search/Xiami.js index 8f432a3..311616a 100644 --- a/server/search/Xiami.js +++ b/server/search/Xiami.js @@ -45,9 +45,9 @@ export default async(request, keyword, artists) => { continue; } - let song = { - src: e.listen_file, - }; + let song = e; + + song.src = e.listen_file; if (!song.src) { return Promise.reject(); diff --git a/server/search/index.js b/server/search/index.js index 7cc534a..3fd3415 100644 --- a/server/search/index.js +++ b/server/search/index.js @@ -5,6 +5,7 @@ import MiGu from './MiGu'; import Kugou from './Kugou'; import Baidu from './Baidu'; import Xiami from './Xiami'; +import Kuwo from './Kuwo'; async function getPreferences() { return new Promise(resolve => { @@ -20,6 +21,7 @@ export default async(keyword, artists) => { var rpOptions = { timeout: 10000, json: true, + jar: true, }; var plugins = []; @@ -27,7 +29,8 @@ export default async(keyword, artists) => { enginers = { 'QQ': true, 'MiGu': true, - 'Xiami': true, + 'Kuwo': true, + 'Xiami': false, 'Kugou': false, 'Baidu': true, }; @@ -62,6 +65,10 @@ export default async(keyword, artists) => { plugins.push(Baidu); } + if (enginers['Kuwo']) { + plugins.push(Kuwo); + } + var rp = require('request-promise-native').defaults(rpOptions); return Promise.all( diff --git a/server/search/test.js b/server/search/test.js index 7cf3a62..5713401 100644 --- a/server/search/test.js +++ b/server/search/test.js @@ -1,16 +1,17 @@ -import search from './Baidu'; +import search from './Kuwo'; async function test() { var res = {}; var rp = require('request-promise-native').defaults({ - proxy: 'http://127.0.0.1:1087', - strictSSL: false + strictSSL: true, + json: true, }); try { - res = await search(rp, 'ε°˜εŸƒ', 'ηŽ‹θ²'); + res = await search(rp, 'ζΌ”ε‘˜', 'θ–›δΉ‹θ°¦'); console.log(res); + console.log(res.purview_roles); } catch (ex) { console.error(ex); } diff --git a/src/js/components/Preferences/Options.js b/src/js/components/Preferences/Options.js index 6011d27..176b472 100644 --- a/src/js/components/Preferences/Options.js +++ b/src/js/components/Preferences/Options.js @@ -225,6 +225,14 @@ class Options extends Component { id="enginerOfKugou" onChange={e => this.setEnginers({ 'Kugou': e.target.checked })} /> +