修复wy源搜索某些歌曲时第一页之后的歌曲无法加载的问题
							parent
							
								
									92351049f1
								
							
						
					
					
						commit
						26aab15e50
					
				| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
- 修复播放下载列表的歌曲时,使用Windows任务栏缩略图工具栏控制按钮的收藏按钮收藏歌曲时的异常问题
 | 
			
		||||
- 修复启用搜索历史但不启用热门搜索时,搜索历史不显示的问题
 | 
			
		||||
- 修复窗口尺寸设置对应的字体大小在启动后不生效的问题
 | 
			
		||||
- 修复wy源搜索某些歌曲时第一页之后的歌曲无法加载的问题
 | 
			
		||||
 | 
			
		||||
### 变更
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
import { httpFetch } from '../../request'
 | 
			
		||||
import { weapi } from './utils/crypto'
 | 
			
		||||
// import { sizeFormate, formatPlayTime } from '../../index'
 | 
			
		||||
import musicDetailApi from './musicDetail'
 | 
			
		||||
// import { httpFetch } from '../../request'
 | 
			
		||||
// import { weapi } from './utils/crypto'
 | 
			
		||||
import { sizeFormate, formatPlayTime } from '../../index'
 | 
			
		||||
// import musicDetailApi from './musicDetail'
 | 
			
		||||
import { eapiRequest } from './utils'
 | 
			
		||||
 | 
			
		||||
let searchRequest
 | 
			
		||||
export default {
 | 
			
		||||
| 
						 | 
				
			
			@ -11,39 +12,14 @@ export default {
 | 
			
		|||
  allPage: 1,
 | 
			
		||||
  musicSearch(str, page, limit) {
 | 
			
		||||
    if (searchRequest && searchRequest.cancelHttp) searchRequest.cancelHttp()
 | 
			
		||||
    searchRequest = httpFetch('https://music.163.com/weapi/search/get', {
 | 
			
		||||
      method: 'post',
 | 
			
		||||
      headers: {
 | 
			
		||||
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
 | 
			
		||||
        origin: 'https://music.163.com',
 | 
			
		||||
      },
 | 
			
		||||
      form: weapi({
 | 
			
		||||
    searchRequest = eapiRequest('/api/cloudsearch/pc', {
 | 
			
		||||
      s: str,
 | 
			
		||||
      type: 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
 | 
			
		||||
      limit,
 | 
			
		||||
      total: page == 1,
 | 
			
		||||
      offset: limit * (page - 1),
 | 
			
		||||
      }),
 | 
			
		||||
    })
 | 
			
		||||
    return searchRequest.promise.then(({ body }) => {
 | 
			
		||||
      // console.log(body)
 | 
			
		||||
      return body && body.code === 200
 | 
			
		||||
        ? musicDetailApi.getList(body.result.songs.map(s => s.id)).then(({ list }) => {
 | 
			
		||||
          this.total = body.result.songCount || 0
 | 
			
		||||
          this.page = page
 | 
			
		||||
          this.allPage = Math.ceil(this.total / limit)
 | 
			
		||||
          return {
 | 
			
		||||
            code: 200,
 | 
			
		||||
            data: {
 | 
			
		||||
              list,
 | 
			
		||||
              allPage: this.allPage,
 | 
			
		||||
              limit,
 | 
			
		||||
              total: this.total,
 | 
			
		||||
              source: 'wy',
 | 
			
		||||
            },
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        : body
 | 
			
		||||
    })
 | 
			
		||||
    return searchRequest.promise.then(({ body }) => body)
 | 
			
		||||
  },
 | 
			
		||||
  getSinger(singers) {
 | 
			
		||||
    let arr = []
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +28,7 @@ export default {
 | 
			
		|||
    })
 | 
			
		||||
    return arr.join('、')
 | 
			
		||||
  },
 | 
			
		||||
  /* handleResult(rawList) {
 | 
			
		||||
  handleResult(rawList) {
 | 
			
		||||
    // console.log(rawList)
 | 
			
		||||
    if (!rawList) return []
 | 
			
		||||
    return rawList.map(item => {
 | 
			
		||||
| 
						 | 
				
			
			@ -102,29 +78,29 @@ export default {
 | 
			
		|||
        typeUrl: {},
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }, */
 | 
			
		||||
  },
 | 
			
		||||
  search(str, page = 1, { limit } = {}, retryNum = 0) {
 | 
			
		||||
    if (++retryNum > 3) return Promise.reject(new Error('try max num'))
 | 
			
		||||
    if (limit == null) limit = this.limit
 | 
			
		||||
    return this.musicSearch(str, page, limit).then(result => {
 | 
			
		||||
      // console.log(result)
 | 
			
		||||
      if (!result || result.code !== 200) return this.search(str, page, { limit }, retryNum)
 | 
			
		||||
      // let list = this.handleResult(result.result.songs || [])
 | 
			
		||||
      let list = this.handleResult(result.result.songs || [])
 | 
			
		||||
 | 
			
		||||
      // if (list == null) return this.search(str, page, { limit }, retryNum)
 | 
			
		||||
      if (list == null) return this.search(str, page, { limit }, retryNum)
 | 
			
		||||
 | 
			
		||||
      // this.total = result.result.songCount || 0
 | 
			
		||||
      // this.page = page
 | 
			
		||||
      // this.allPage = Math.ceil(this.total / this.limit)
 | 
			
		||||
      this.total = result.result.songCount || 0
 | 
			
		||||
      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: 'wy',
 | 
			
		||||
      // })
 | 
			
		||||
      return result.data
 | 
			
		||||
      return {
 | 
			
		||||
        list,
 | 
			
		||||
        allPage: this.allPage,
 | 
			
		||||
        limit: this.limit,
 | 
			
		||||
        total: this.total,
 | 
			
		||||
        source: 'wy',
 | 
			
		||||
      }
 | 
			
		||||
      // return result.data
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,22 @@
 | 
			
		|||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/util/crypto.js
 | 
			
		||||
import { createCipheriv, publicEncrypt, constants, randomBytes } from 'crypto'
 | 
			
		||||
import { createCipheriv, createDecipheriv, publicEncrypt, randomBytes, createHash, constants } from 'crypto'
 | 
			
		||||
const iv = Buffer.from('0102030405060708')
 | 
			
		||||
const presetKey = Buffer.from('0CoJUm6Qyw8W8jud')
 | 
			
		||||
const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q')
 | 
			
		||||
const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
 | 
			
		||||
const publicKey = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----'
 | 
			
		||||
const eapiKey = 'e82ckenh8dichen8'
 | 
			
		||||
 | 
			
		||||
const aesEncrypt = (buffer, mode, key, iv) => {
 | 
			
		||||
  const cipher = createCipheriv('aes-128-' + mode, key, iv)
 | 
			
		||||
  const cipher = createCipheriv(mode, key, iv)
 | 
			
		||||
  return Buffer.concat([cipher.update(buffer), cipher.final()])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const aesDecrypt = function(cipherBuffer, mode, key, iv) {
 | 
			
		||||
  let decipher = createDecipheriv(mode, key, iv)
 | 
			
		||||
  return Buffer.concat([decipher.update(cipherBuffer), decipher.final()])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const rsaEncrypt = (buffer, key) => {
 | 
			
		||||
  buffer = Buffer.concat([Buffer.alloc(128 - buffer.length), buffer])
 | 
			
		||||
  return publicEncrypt({ key: key, padding: constants.RSA_NO_PADDING }, buffer)
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +26,7 @@ export const weapi = object => {
 | 
			
		|||
  const text = JSON.stringify(object)
 | 
			
		||||
  const secretKey = randomBytes(16).map(n => (base62.charAt(n % 62).charCodeAt()))
 | 
			
		||||
  return {
 | 
			
		||||
    params: aesEncrypt(Buffer.from(aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64')), 'cbc', secretKey, iv).toString('base64'),
 | 
			
		||||
    params: aesEncrypt(Buffer.from(aesEncrypt(Buffer.from(text), 'aes-128-cbc', presetKey, iv).toString('base64')), 'aes-128-cbc', secretKey, iv).toString('base64'),
 | 
			
		||||
    encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex'),
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -31,3 +37,18 @@ export const linuxapi = object => {
 | 
			
		|||
    eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '').toString('hex').toUpperCase(),
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const eapi = (url, object) => {
 | 
			
		||||
  const text = typeof object === 'object' ? JSON.stringify(object) : object
 | 
			
		||||
  const message = `nobody${url}use${text}md5forencrypt`
 | 
			
		||||
  const digest = createHash('md5').update(message).digest('hex')
 | 
			
		||||
  const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}`
 | 
			
		||||
  return {
 | 
			
		||||
    params: aesEncrypt(Buffer.from(data), 'aes-128-ecb', eapiKey, '').toString('hex').toUpperCase(),
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const eapiDecrypt = cipherBuffer => {
 | 
			
		||||
  return aesDecrypt(cipherBuffer, 'aes-128-ecb', eapiKey, '').toString()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
import { httpFetch } from '../../../request'
 | 
			
		||||
import { eapi } from './crypto'
 | 
			
		||||
 | 
			
		||||
export const eapiRequest = (url, data) => {
 | 
			
		||||
  return httpFetch('http://interface.music.163.com/eapi/batch', {
 | 
			
		||||
    method: 'post',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
 | 
			
		||||
      origin: 'https://music.163.com',
 | 
			
		||||
      // cookie: 'os=pc; deviceId=A9C064BB4584D038B1565B58CB05F95290998EE8B025AA2D07AE; osver=Microsoft-Windows-10-Home-China-build-19043-64bit; appver=2.5.2.197409; channel=netease; MUSIC_A=37a11f2eb9de9930cad479b2ad495b0e4c982367fb6f909d9a3f18f876c6b49faddb3081250c4980dd7e19d4bd9bf384e004602712cf2b2b8efaafaab164268a00b47359f85f22705cc95cb6180f3aee40f5be1ebf3148d888aa2d90636647d0c3061cd18d77b7a0; __csrf=05b50d54082694f945d7de75c210ef94; mode=Z7M-KP5(7)GZ; NMTID=00OZLp2VVgq9QdwokUgq3XNfOddQyIAAAF_6i8eJg; ntes_kaola_ad=1',
 | 
			
		||||
    },
 | 
			
		||||
    form: eapi(url, data),
 | 
			
		||||
  })
 | 
			
		||||
  // requestObj.promise = requestObj.promise.then(({ body }) => {
 | 
			
		||||
  //   // console.log(raw)
 | 
			
		||||
  //   console.log(body)
 | 
			
		||||
  //   // console.log(eapiDecrypt(raw))
 | 
			
		||||
  //   // return eapiDecrypt(raw)
 | 
			
		||||
  //   return body
 | 
			
		||||
  // })
 | 
			
		||||
  // return requestObj
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue