vue-music:歌詞獲取並解析爲json

播放器歌詞數據須要從qq官網上抓取,打開qq音樂任意一首歌曲的播放頁面,在chrome的Network中搜索lyric,即獲取歌詞的接口
歌詞獲取接口vue

1. 配置接口

qq對接口進行了安全控制,在devserver中模擬請求頭等從而避開
在config文件夾中index.js文件中,配置proxyTableios

proxyTable: {
      //target:真實請求的值
      //bypass:對應的函數是請求以前能夠進行的操做
      //req這個參數是請求的信息,能夠在這裏設置請求頭信息
      '/api/lyric':{
        target: 'https://szc.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg',
        bypass: function (req, res, proxyOptions) {
          req.headers.referer = 'https://c.y.qq.com';
          req.headers.host = 'c.y.qq.com';
        },
        pathRewrite: {
          '^/api/lyric': ''
        }
      }
    }

2. 調取接口的API

在api文件夾下建立song.jschrome

export function getLyric(mid) {
  const url = '/api/lyric'
  const data = Object.assign({}, commonParams, {
    songmid: mid,
    platform: 'yqq',
    hostUin: 0,
    needNewCode: 0,
    pcachetime: +new Date(),
    format: 'json',
    g_tk: 67232076
  })

  return axios.get(url, {
    params: data
  }).then((res) => {
    if (typeof res.data === 'string') {
      //返回的jsonp格式,利用正則,提取咱們須要的json字段
      const reg = /^\w+\(({[^()]+})\)$/
      var matches = res.data.match(reg)
      if (matches) {
        let val = JSON.parse(matches[1])
        //爲何用Promise:爲了後邊的方法調用的時候,進一步then,操做數據
        return Promise.resolve(val)
      }
    }
  })
}

3.在Song類中調用

爲何寫在class Song{}中:由於這樣能夠它的實例直接調用本身的歌詞json

export default class Song {
  ....
  //當初沒有搞懂爲何lyric再也不constructor中定義:下面的if判斷,防止重複請求歌詞
  getLyric() {
    if (this.lyric) {
      return Promise.resolve(this.lyric)
    }
    //這裏用Promsie返回,一樣的道理:後面調用這個方法,方便進一步操做數據,同2中的promsie
    return new Promise((resolve, reject) => {
      getLyric(this.mid).then((res) => {
        if (res.code === ERR_OK) {
          //返回數據的是 base64 的字符串,須要解碼,這裏用到了第三方庫: js-base64
          this.lyric = Base64.decode(res.lyric)
          resolve(this.lyric)
        } else {
          reject(new Error('no lyric'))
        }
      })
    })
  }
}

3.真正調取方法

在player.vue中methods,調取方法axios

getLyric() {
  //在2中,方法定義在class Song{}類中,這個時候this.currentSong是類的實例,能夠直接調用定義的實例方法
  this.currentSong.getLyric().then((lyric) => {
    //利用第三方庫: js-lyric ,解析咱們的歌詞,生成方便操做的對象
    //new Lyric生成的實例,還有一些api方便使用play、stop等等
    //this.handleLyric回調函數handleLyric(lineNum,txt):(當前播放的行數,當前播放的文字)
    this.currentLyric = new Lyric(lyric, this.handleLyric)
    if (this.playing) {
      this.currentLyric.play()
    }
  }).catch(() => {
    //若是歌詞有問題,初始化
    this.currentLyric = null
    this.playingLyric = ''
    this.currentLineNum = 0
  })
},

4.在watch裏的currentSong中調用this.getLyric()

相關文章
相關標籤/搜索