lrc是英文lyric(歌詞)的縮寫,被用作歌詞文件的擴展名。以lrc爲擴展名的歌詞文件能夠在各種數碼播放器中同步顯示。LRC 歌詞是一種包含着「:」形式的「標籤(tag)」的、基於純文本的歌詞專用格式。這種歌詞文件既能夠用來實現卡拉OK功能(須要專門程序),又能以普通的文字處理軟件查看、編輯。固然,實際操做時一般是用專門的LRC歌詞編輯軟件進行高效編輯的。javascript
lrc歌詞文本中含有兩類標籤:java
一是標識標籤,其格式爲「[標識名:值]」主要包含如下預約義的標籤:正則表達式
[ar:藝人名] [ti:曲名] [al:專輯名] [by:編者(指編輯LRC歌詞的人)] [offset:時間補償值] 其單位是毫秒,正值表示總體提早,負值相反。這是用於整體調整顯示快慢的,(但多數的MP3可能不會支持這種標籤)。
二是時間標籤,形式爲「[mm:ss]」或「[mm:ss.ff]」(分鐘數:秒數.毫秒數),時間標籤需位於某行歌詞中的句首部分,一行歌詞能夠包含多個時間標籤(好比歌詞中的迭句部分)。當歌曲播放到達某一時間點時,MP3就會尋找對應的時間標籤並顯示標籤後面的歌詞文本,這樣就完成了「歌詞同步」的功能。
形式爲"[mm:ss]"(分鐘數:秒數)或"[mm:ss.ff]"。數字須爲非負整數, 好比"[12:34.50]"是有效的,而"[0x0C:-34.50]"無效。標籤無須排序。數組
解析思路以下併發
根據lrc字符串,經過換行符分紅數組的每一項。函數
對每行進行正則表達式匹配,若是匹配上的是時間正則表達式,則對這行進行時間邏輯處理。相應的,若是是曲做者或者演唱者或者是偏移量,則進行相對應的邏輯處理。相應的正則表達式this
_regAr = /\[ar:(.+)\]/, _regTi = /\[ti:(.+)\]/, _regAl = /\[al:(.+)\]/, _regBy = /\[by:(.+)\]/, _regOffset = /\[offset:.+\]/, _regTime = /\[\d+:\d+(\.\d+)?\]/g,
以[01:10.50]爲例,統一解析成以秒爲單位的70.5秒。轉換成這樣是爲了讓時間的表示更簡潔,可是在進行顯示和存儲歌詞以前還需提供一個format函數將時間計算回去。翻譯
輸出結果爲:按照時間排序以後的數組,數組每一項爲以time,和txt爲key的對象。Lrclist以下的格式code
0: Object time: 9.841 txt: "It's been a long day without you my friend" 1: Object time: 16.8 txt: "And I'll tell you all about it when
若是須要歌詞的Lrctxt文本,就能夠藉助format函數將時間將Lrclist中的每一項進行拼接成以下的格式:orm
0: "[00:09.841]It's been a long day without you my friend" 1: "[00:16.800]And I'll tell you all about it when I see you again" 2: "[00:22.600]We've come a long way from where we began"
滾動歌詞的界面是將內容插入到播放父節點this.__ncontent下面:
_u._$forEach(Lrclist,function(_item){ _lines.push('<li>'+_item.txt+'</li>'); } this.__ncontent.innerHTML = _lines.join('');
當歌曲在播放的過程當中,根據播放的時間_time,從後向前依次對比時間,找到對應的index記錄爲currnetplay,經過更改樣式,表示是當前播放的歌詞。
而滾動的效果能夠經過總體改變margin-top來實現滾動的效果。在項目中簡化處理是直接設置li個父節點top爲播放父節點的height/2-li的行高。
這裏存在一個問題,若是一行歌詞特別長,顯示的時候進行了換行,那麼這個距離計算的就會有問題。固然,一種是經過js計算出幾行;另外是加個橫向的滾動條,醜是醜了點,確實是比較簡單的處理了。
當帶翻譯的歌詞滾動播放的時候,咱們但願連帶翻譯歌詞一塊滾動。在這裏,我是經過對解析出來的lrclist中的時間找到對應的翻譯歌詞translist中的索引,來爲列表中的每一項增長key爲transtxt的內容:
_u._$forEach(_list, function(_item){ var _index = _u._$indexOf(_translist, function(_item0){ return _item0.time==_item.time; }); if(_index!=-1){ var _trans = _translist[_index]; } if(_trans){ _item.transtxt = _trans.txt||''; } });
這樣解析出來的歌詞對象就變成:
0: Object time: 9.841 transtxt: "沒有老友你的陪伴 日子真是漫長" txt: "It's been a long day without you my
滾動時候的顯示規則同上,只不過在滾動時,top值要減去 2*li 的行高了。
在滾動播放的過程當中,經常但願根據播放的效果對歌詞進行總體的,或者當前句的微調。
這些需求就是直接操做歌詞的時間軸了。
總體偏移一個offset就是將解析出來的lrclist中的每一item中的時間加/減一個offset,一般微調的話,毫秒級別了。
當前句偏移,關鍵是找到currentplay,這個在前面已經介紹了。
以後偏移,也是找到currentplay,將該索引以後的item的時間加/減一個偏移量。
菜鳥一枚,但願本身能將寫博客的習慣養成,併發揚光大。嗯嗯。。自勉。。。