1、首先要安装ustbhuangyi提供的第三方库 lyric-parser,以及配合Scroll组件(不详述)。
import Lyric from 'lyric-parser'
import Scroll from 'base/scroll/scroll'
//
watch: {
currentSong (newSong, oldSong) {
if (newSong.id === oldSong.id) {
return
}
this.$nextTick(() => {
this.$refs.audio.play()
this.getLyric() // 调用获取歌词方法
})
}
}
//
methods: {
getLyric () {
this.currentSong.getLyric().then(lyric => {
// 下述的this.handleLyric是回调函数,指当歌曲执行play()方法时会根据播放索引持续派发回调事件
this.currentLyric = new Lyric(lyric, this.handleLyric)
if (this.playing) {
this.currentLyric.play() // 当vuex的playing为播放时,同步执行歌词的play()
}
})
},
handleLyric ({lineNum, txt}) {
// 回调事件包含两个参数 lineNum,当前play()事件的歌词索引,以及歌词文本
this.currentLineNum = lineNum
// 调用scrollToElement方法,让其跳转当前行数-5的位置,时刻保持歌词居中显示
if (lineNum > 5) {
let lineEl = this.$refs.lyricLine[lineNum - 5]
this.$refs.lyricList.scrollToElement(lineEl, 1000)
} else {
this.$refs.lyricList.scrollTo(0, 0, 1000)
}
}
}
整体效果
2019年5月11日11:22:47 发烧未痊愈的第4天好像,呵呵。
为什么那么努力?不趁机睡个大觉?哈哈哈,问得好,那你活着干嘛呢,我不甘于苟,我有家人,我也有爱人,我少的是时间,你会说我还年轻,谁告诉你的呢,时间会等你吗?时间等过谁,时间永远快人一等,时间是万物的主宰者,没必要和时间赛跑,你比不了,但是你可以和时间一样珍惜时间,一秒一秒滴答滴答。做事,一厘一毫造就术业,为爱的人,为梦想。
2、理一理思路吧
因为一切都是基于现有的接口,故后端接口的设计,以及数据的架构,应是最难的部分了,已经跳过了。
1、歌词的抓取,采用代理,修改referer,origin。
2、歌词数据的Base64解码lyric,并通过lyric-parser 实例new Lyric(lyric, handleLyric)(实际是提供了类封装多个方法),核心是handleLyric回调函数。
3、歌词的显示,需要将全部歌词v-for入div内,并传入Scroll组件内。
4、歌词的播放,new Lyric类提供play()方法,开始向外派发handleLyric回调函数,并传入 handleLyric(lineNum,txt) 当前歌词索引,和歌词文本。故play()方法需要和audio.play()同步开启,做到视听同步。
5、歌词的动态居中滚动,当前索引已知很容易设置高亮。居中滚动是用到了better-scroll的scrollToElement方法,this.$refs.scroll.scrollToElement($this.refs.lyricList, 1000) ,跳转至该dom并置顶以1000ms的动画执行。然后通过索引减5即可实现居中。
6、一系列优化,比如单曲循环,调用this.currentLyric.seek(0),这个传入的是时间毫秒,包括拖动进度也是。实现曲与词同步。暂停,调用this.currentLyric.stop(),播放等等。