關(guān)于項(xiàng)目
該項(xiàng)目基于HTML5 audio api 完成的一個(gè)分享版簡(jiǎn)易音樂(lè)播放器。
關(guān)于歌詞
Lrc歌詞文件:大部分MP3顯示歌詞的方法使用的是lrc格式的歌詞文件,也是當(dāng)前網(wǎng)絡(luò)上最流行的一種歌詞格式。LRC通常有合并和展開兩種形式:合并LRC歌詞是將歌詞內(nèi)容相同的合并起來(lái),多個(gè)時(shí)間標(biāo)簽對(duì)應(yīng)一句歌詞;展開LRC是一個(gè)時(shí)間標(biāo)簽對(duì)應(yīng)一句歌詞。合并LRC可以節(jié)省磁盤空間。

lrc_1.png

lrc_2.png
解析歌詞
parseLyric: function(text){
//將文本分隔成一行一行,存入數(shù)組
var lines = text.split('\n'),
//用于匹配時(shí)間的正則表達(dá)式,匹配的結(jié)果類似[xx:xx.xx]
pattern = /\[\d{2}:\d{2}.\d{2}\]/g,
//保存最終結(jié)果的數(shù)組
result = [];
//去掉不含時(shí)間的行
while (!pattern.test(lines[0])) {
lines = lines.slice(1);
};
//上面用'\n'生成生成數(shù)組時(shí),結(jié)果中最后一個(gè)為空元素,這里將去掉
lines[lines.length - 1].length === 0 && lines.pop();
lines.forEach(function(v /*數(shù)組元素值*/ , i /*元素索引*/ , a /*數(shù)組本身*/ ) {
//提取出時(shí)間[xx:xx.xx]
var time = v.match(pattern),
//提取歌詞
value = v.replace(pattern, '');
//因?yàn)橐恍欣锩婵赡苡卸鄠€(gè)時(shí)間,所以time有可能是[xx:xx.xx][xx:xx.xx][xx:xx.xx]的形式,需要進(jìn)一步分隔
time.forEach(function(v1, i1, a1) {
//去掉時(shí)間里的中括號(hào)得到xx:xx.xx
var t = v1.slice(1, -1).split(':');
//將結(jié)果壓入最終數(shù)組
result.push([parseInt(t[0], 10) * 60 + parseFloat(t[1]), value]);
});
});
//最后將結(jié)果數(shù)組中的元素按時(shí)間大小排序,以便保存之后正常顯示歌詞
result.sort(function(a, b) {
return a[0] - b[0];
});
return result;
}
解析歌詞
var lyric = []; //歌詞結(jié)果數(shù)組
this.audio.addEventListener('timeupdate', function(){
var curTime = this.currentTime;
lyric.forEach(function(v, i){
if (curTime > v[0]) { // 當(dāng)前時(shí)間大于歌詞對(duì)應(yīng)的時(shí)間,高亮顯示歌詞
$('#line-'+ (i>0 ? i-1 : i)).classList.remove('current');
$('#line-'+ i).classList.add('current'); // 設(shè)置當(dāng)前歌詞樣式
$lyric.style.transform = 'translate3d(0,-'+ 42*i +'px,0)'; // 每行歌詞行高是42px
}
});
});
audio api
- 屬性
- currentTime 設(shè)置或返回音頻/視頻中的當(dāng)前播放位置(以秒計(jì))
- duration 返回當(dāng)前音頻/視頻的長(zhǎng)度(以秒計(jì))
- 事件
- canplay 當(dāng)瀏覽器可以播放音頻/視頻時(shí)
- play 當(dāng)音頻/視頻已開始或不再暫停時(shí)
- ended 當(dāng)目前的播放列表已結(jié)束時(shí)
- timeupdate 當(dāng)目前的播放位置已更改時(shí)
項(xiàng)目預(yù)覽
1. npm install
2. npm run dev