完成聚合搜索功能

pull/96/head
lyswhut 2019-09-21 20:05:56 +08:00
parent ef9eb83a75
commit 5321469c1d
6 changed files with 151 additions and 112 deletions

View File

@ -1,5 +1,6 @@
### 新增 ### 新增
- 新增音乐**聚合搜索**,目前支持酷我、酷狗、百度源搜索
- 新增代理功能 - 新增代理功能
### 优化 ### 优化

View File

@ -1,8 +1,5 @@
import music from '../../utils/music' import music from '../../utils/music'
const sources = [{ const sources = []
id: 'all',
name: '聚合搜索',
}]
const sourceList = {} const sourceList = {}
const sourceMaxPage = {} const sourceMaxPage = {}
for (const source of music.sources) { for (const source of music.sources) {
@ -19,6 +16,11 @@ for (const source of music.sources) {
sourceMaxPage[source.id] = 0 sourceMaxPage[source.id] = 0
} }
sources.push({
id: 'all',
name: '聚合搜索',
})
// state // state
const state = { const state = {
sourceList, sourceList,
@ -80,7 +82,7 @@ const mutations = {
total += source.total total += source.total
limit += source.limit limit += source.limit
} }
list.sort() list.sort((a, b) => b.name.charCodeAt(0) - a.name.charCodeAt(0))
state.allPage = Math.max(...pages) state.allPage = Math.max(...pages)
state.total = total state.total = total
state.limit = limit state.limit = limit

View File

@ -3,10 +3,12 @@ import api_source from '../api-source'
import musicInfo from './musicInfo' import musicInfo from './musicInfo'
import songList from './songList' import songList from './songList'
import { httpFatch } from '../../request' import { httpFatch } from '../../request'
import musicSearch from './musicSearch'
const bd = { const bd = {
leaderboard, leaderboard,
songList, songList,
musicSearch,
getMusicUrl(songInfo, type) { getMusicUrl(songInfo, type) {
return api_source('bd').getMusicUrl(songInfo, type) return api_source('bd').getMusicUrl(songInfo, type)
}, },

View File

@ -1,143 +1,83 @@
// import '../../polyfill/array.find' // import '../../polyfill/array.find'
// import jshtmlencode from 'js-htmlencode' // import jshtmlencode from 'js-htmlencode'
import { httpGet, cancelHttp } from '../../request' import { httpFatch } from '../../request'
import { formatPlayTime, decodeName } from '../../index' import { formatPlayTime } from '../../index'
// import { debug } from '../../utils/env' // import { debug } from '../../utils/env'
import { formatSinger } from './util' // import { formatSinger } from './util'
let searchRequest
export default { export default {
regExps: {
mInfo: /bitrate:(\d+),format:(\w+),size:([\w.]+)/,
},
_musicSearchRequestObj: null,
_musicSearchPromiseCancelFn: null,
limit: 30, limit: 30,
total: 0, total: 0,
page: 0, page: 0,
allPage: 1, allPage: 1,
// cancelFn: null,
musicSearch(str, page) { musicSearch(str, page) {
if (this._musicSearchRequestObj != null) { if (searchRequest && searchRequest.cancelHttp) searchRequest.cancelHttp()
cancelHttp(this._musicSearchRequestObj) searchRequest = httpFatch(`http://tingapi.ting.baidu.com/v1/restserver/ting?from=android&version=5.6.5.6&method=baidu.ting.search.merge&format=json&query=${encodeURIComponent(str)}&page_no=${page}&page_size=${this.limit}&type=0&data_source=0&use_cluster=1`)
this._musicSearchPromiseCancelFn(new Error('取消http请求')) return searchRequest.promise.then(({ body }) => body)
}
return new Promise((resolve, reject) => {
this._musicSearchPromiseCancelFn = reject
this._musicSearchRequestObj = httpGet(`http://search.kuwo.cn/r.s?client=kt&all=${encodeURIComponent(str)}&pn=${page - 1}&rn=${this.limit}&uid=794762570&ver=kwplayer_ar_9.2.2.1&vipver=1&show_copyright_off=1&newver=1&ft=music&cluster=0&strategy=2012&encoding=utf8&rformat=json&vermerge=1&mobi=1&issubtitle=1`, (err, resp, body) => {
this._musicSearchRequestObj = null
this._musicSearchPromiseCancelFn = null
if (err) {
console.log(err)
reject(err)
}
resolve(body)
})
})
}, },
// getImg(songId) {
// return httpGet(`http://player.kuwo.cn/webmusic/sj/dtflagdate?flag=6&rid=MUSIC_${songId}`)
// },
// getLrc(songId) {
// return httpGet(`http://mobile.kuwo.cn/mpage/html5/songinfoandlrc?mid=${songId}&flag=0`)
// },
handleResult(rawData) { handleResult(rawData) {
const result = [] // console.log(rawData)
for (let i = 0; i < rawData.length; i++) { return rawData.map(item => {
const info = rawData[i]
let songId = info.MUSICRID.replace('MUSIC_', '')
// const format = (info.FORMATS || info.formats).split('|')
if (!info.MINFO) {
console.log('mInfo is undefined')
return null
}
const types = [] const types = []
const _types = {} const _types = {}
let size = null
let infoArr = info.MINFO.split(';') let itemTypes = item.all_rate.split(',')
infoArr.forEach(info => { if (itemTypes.includes('128')) {
info = info.match(this.regExps.mInfo) types.push({ type: '128k', size })
if (info) { _types['128k'] = {
switch (info[2]) { size,
case 'flac':
types.push({ type: 'flac', size: info[3] })
_types.flac = {
size: info[3].toLocaleUpperCase(),
}
break
case 'ape':
types.push({ type: 'ape', size: info[3] })
_types.ape = {
size: info[3].toLocaleUpperCase(),
}
break
case 'mp3':
switch (info[1]) {
case '320':
types.push({ type: '320k', size: info[3] })
_types['320k'] = {
size: info[3].toLocaleUpperCase(),
}
break
case '192':
types.push({ type: '192k', size: info[3] })
_types['192k'] = {
size: info[3].toLocaleUpperCase(),
}
break
case '128':
types.push({ type: '128k', size: info[3] })
_types['128k'] = {
size: info[3].toLocaleUpperCase(),
}
break
}
break
}
} }
}) }
types.reverse() if (itemTypes.includes('320')) {
types.push({ type: '320k', size })
_types['320k'] = {
size,
}
}
if (itemTypes.includes('flac')) {
types.push({ type: 'flac', size })
_types.flac = {
size,
}
}
// types.reverse()
let interval = parseInt(info.DURATION) return {
singer: item.author.replace(',', '、'),
result.push({ name: item.title,
name: decodeName(info.SONGNAME), albumName: item.album_title,
singer: formatSinger(decodeName(info.ARTIST)), albumId: item.album_id,
source: 'kw', source: 'bd',
// img = (info.album.name === '' || info.album.name === '空') interval: formatPlayTime(parseInt(item.file_duration)),
// ? `http://player.kuwo.cn/webmusic/sj/dtflagdate?flag=6&rid=MUSIC_160911.jpg` songmid: item.song_id,
// : `https://y.gtimg.cn/music/photo_new/T002R500x500M000${info.album.mid}.jpg`
songmid: songId,
albumId: decodeName(info.ALBUMID || ''),
interval: Number.isNaN(interval) ? 0 : formatPlayTime(interval),
albumName: info.ALBUM ? decodeName(info.ALBUM) : '',
lyric: null,
img: null, img: null,
lrc: null,
types, types,
_types, _types,
typeUrl: {}, typeUrl: {},
}) }
} })
return result
}, },
search(str, page = 1, { limit }) { search(str, page = 1, { limit } = {}) {
if (limit != null) this.limit = limit if (limit != null) this.limit = limit
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
return this.musicSearch(str, page).then(result => { return this.musicSearch(str, page).then(result => {
if (!result || (result.TOTAL !== '0' && result.SHOW === '0')) return this.search(str, page, { limit }) if (!result || result.error_code !== 22000) return this.search(str, page, { limit })
let list = this.handleResult(result.abslist) let list = this.handleResult(result.result.song_info.song_list)
if (list == null) return this.search(str, page, { limit }) if (list == null) return this.search(str, page, { limit })
this.total = parseInt(result.TOTAL) this.total = result.result.song_info.total
this.page = page this.page = page
this.allPage = Math.ceil(this.total / this.limit) this.allPage = Math.ceil(this.total / this.limit)
return Promise.resolve({ return Promise.resolve({
list, list,
allPage: this.allPage, allPage: this.allPage,
limit: this.limit,
total: this.total, total: this.total,
source: 'bd',
}) })
}) })
}, },

View File

@ -1,10 +1,12 @@
import leaderboard from './leaderboard' import leaderboard from './leaderboard'
import api_source from '../api-source' import api_source from '../api-source'
import songList from './songList' import songList from './songList'
import musicSearch from './musicSearch'
const kg = { const kg = {
leaderboard, leaderboard,
songList, songList,
musicSearch,
getMusicUrl(songInfo, type) { getMusicUrl(songInfo, type) {
return api_source('kg').getMusicUrl(songInfo, type) return api_source('kg').getMusicUrl(songInfo, type)
}, },

View File

@ -0,0 +1,92 @@
// import '../../polyfill/array.find'
// import jshtmlencode from 'js-htmlencode'
import { httpFatch } from '../../request'
import { formatPlayTime, sizeFormate } from '../../index'
// import { debug } from '../../utils/env'
// import { formatSinger } from './util'
let searchRequest
export default {
limit: 30,
total: 0,
page: 0,
allPage: 1,
musicSearch(str, page) {
if (searchRequest && searchRequest.cancelHttp) searchRequest.cancelHttp()
searchRequest = httpFatch(`http://ioscdn.kugou.com/api/v3/search/song?keyword=${encodeURIComponent(str)}&page=${page}&pagesize=${this.limit}&showtype=10&plat=2&version=7910&tag=1&correct=1&privilege=1&sver=5`)
return searchRequest.promise.then(({ body }) => body)
},
handleResult(rawData) {
// console.log(rawData)
let ids = new Set()
const list = []
rawData.forEach(item => {
if (ids.has(item.audio_id)) return
ids.add(item.audio_id)
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['320filesize'] !== 0) {
let size = sizeFormate(item['320filesize'])
types.push({ type: '320k', size, hash: item['320hash'] })
_types['320k'] = {
size,
hash: item['320hash'],
}
}
if (item.sqfilesize !== 0) {
let size = sizeFormate(item.sqfilesize)
types.push({ type: 'flac', size, hash: item.sqhash })
_types.flac = {
size,
hash: item.sqhash,
}
}
list.push({
singer: item.singername,
name: item.songname,
albumName: item.album_name,
albumId: item.album_id,
songmid: item.audio_id,
source: 'kg',
interval: formatPlayTime(item.duration),
img: null,
lrc: null,
hash: item.hash,
types,
_types,
typeUrl: {},
})
})
return list
},
search(str, page = 1, { limit } = {}) {
if (limit != null) this.limit = limit
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
return this.musicSearch(str, page).then(result => {
if (!result || result.errcode !== 0) return this.search(str, page, { limit })
let list = this.handleResult(result.data.info)
if (list == null) return this.search(str, page, { limit })
this.total = result.data.total
this.page = page
this.allPage = Math.ceil(this.total / this.limit)
return Promise.resolve({
list,
allPage: this.allPage,
limit: this.limit,
total: this.total,
source: 'kg',
})
})
},
}