js解析lrc 实现lrc歌词同步滚动效果
這兩天想著做一個(gè)h5的網(wǎng)頁播放器,實(shí)現(xiàn)歌詞同步滾動
但是上網(wǎng)找了很多資料,竟發(fā)現(xiàn)沒有比較完善的代碼供參考,但是無意間看到了百度的千千音樂有這樣的效果,就想著一定能通過js實(shí)現(xiàn)
經(jīng)過兩三天的努力,終于做出了這樣的效果
實(shí)現(xiàn)功能
- 歌詞同步滾動
- 同步歌詞高亮效果
代碼實(shí)現(xiàn)
首先,在body中加audio 和 放歌詞的ul標(biāo)簽
<div><ul id="lrclist" style="transform: translateY(250px);"><!-- 保證歌詞在正中間 --></ul> </div> <audio id="audio" src="audio/1.mp3" controls="controls" autoplay="true"></audio>然后就是讀取lrc文件,在進(jìn)行解析,解析出歌詞及對應(yīng)的時(shí)間
 一般的思路是這樣的:通過Ajax或其他方式讀取lrc文件
 但我的專業(yè)是后端開發(fā),js,啥的,都是自學(xué)的,于是遇到了不少坑,,在我千方百計(jì)想獲取lrc文件時(shí),總是報(bào)錯,,只能通過http,data 協(xié)議獲取文件,加上我用的是notepad開發(fā)的,調(diào)試了億遍都失敗
?
?
最后只好放棄了,我把lrc數(shù)據(jù)直接定義在js中,最后實(shí)現(xiàn)了同樣的效果,
var lrcJSON = {"[00:16.810]":"誰にも言えない孤獨(dú)を抱えたまま1人で泣いてた","[00:28.040]":"誰にも上手に笑えない僕ら 2人出會って笑った","[00:39.710]":"","[00:40.410]":"真夜中過ぎに 想像の奧に","[00:46.150]":"どうしようもない気持ちをただ押しやって","[00:50.780]":"","[00:51.480]":"サヨナラ 僕らはきっと生まれ変われるから","[00:57.030]":"悲しみに手を振るんでしょう","[01:01.190]":"そしていつか 空っぽのままの心に燈りをともすように","[01:08.630]":"とぎれとぎれの 言葉を探して繋ぎ止めた","[01:14.390]":"それでもたった二人の世界は続いて行くんだ","[01:20.190]":"空に祈るように どうか永遠(yuǎn)に","[01:29.380]":"","[01:43.670]":"白?黒?壱?零 僕らは選ぶ事を迫られてばかり","[01:54.940]":"そうして殘った大事な物を壊れるほど抱きしめていた","[02:06.670]":"","[02:07.670]":"明け方過ぎの光の先に","[02:13.530]":"ほんの少しだけ未來が見えた気がして","[02:18.110]":"","[02:18.810]":"バカげた夢だってきっと願い続けるから","[02:24.330]":"奇跡に近づくんでしょう","[02:28.590]":"それは君の弱さの隣に見つけた強(qiáng)さの欠片だって","[02:36.160]":"とぎれとぎれの 言葉を探して繋ぎ止めた","[02:41.700]":"瞼の奧に滲んだ世界を守ってゆくんだ","[02:47.470]":"空に祈るように 君と誓う明日","[02:58.720]":"","[03:08.900]":"不自由な思いが重なり合ったら","[03:14.390]":"そうさ誰より自由になれた","[03:20.390]":"足りないものを埋め合うように","[03:25.700]":"疑いもせず 支えあいながら","[03:31.610]":"","[03:34.060]":"サヨナラ 僕らはきっと生まれ変われるから","[03:39.490]":"悲しみに手を振るんでしょう","[03:44.450]":"そしていつか 空っぽのままの心に燈りをともすように","[03:51.620]":"とぎれとぎれの 言葉を探して繋ぎ止めた","[03:57.190]":"それでもたった二人の世界は続いて行くんだ","[04:03.000]":"空に祈るように どうか永遠(yuǎn)に…"};(有需要的可以仿照網(wǎng)上的Ajax獲取lrc文件,再進(jìn)行解析)
(不過lrc歌詞文件可沒有那么簡單,開頭可能還有歌名,歌手等信息,后邊可能還有歌詞對應(yīng)的翻譯。這里我是簡化了數(shù)據(jù)。)
 然后獲取lrc數(shù)據(jù),在ul中填充歌詞,同時(shí)獲取歌詞對應(yīng)的時(shí)間數(shù)據(jù)
接下來是播放時(shí)的自動滾動,用到了audio的timeupdate事件
audio.ontimeupdate = function() {//audio時(shí)間改變事件currentTime = audio.currentTime;for (j=currentLine, len=lrcTime.length; j<len; j++){if (currentTime<lrcTime[j+1] && currentTime>lrcTime[j]){currentLine = j;ppxx = 250-(currentLine*32);ul.style.transform = "translateY("+ppxx+"px)";$li.get(currentLine-1).className="";console.log("on"+currentLine);$li.get(currentLine).className="on";break;}} };最后是調(diào)整播放位置時(shí)觸發(fā)的audio的seeked事件
audio.onseeked = function() {//audio進(jìn)度更改后事件currentTime = audio.currentTime;console.log(" off"+currentLine);$li.get(currentLine).className="";for (k=0, len=lrcTime.length; k<len; k++){if (currentTime<lrcTime[k+1] && currentTime<lrcTime[k]){currentLine = k;break;}} };實(shí)現(xiàn)效果
最后附上完整代碼
<!DOCTYPE html> <html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"><title>LRC</title><script src="js/jquery.js"></script><style>div{width:340px;height:500px;margin:0 auto;overflow:hidden;}ul{transition-duration: 600ms;}ul, li{list-style:none;padding: 0;margin: 0;}li.on{color: red;}p{overflow: hidden;text-overflow: ellipsis;height: 16px;line-height: 16px;-webkit-line-clamp: 1;-webkit-box-orient: vertical;display: -webkit-box;text-align: center;margin-top: 0;margin-bottom: 16px;}audio{margin-top: 10px;}</style></head><body><div><ul id="lrclist" style="transform: translateY(250px);"><!-- 保證歌詞在正中間 --></ul></div><audio id="audio" src="audio/1.mp3" controls="controls" autoplay="true"></audio><script>var lrcJSON = {"[00:16.810]":"誰にも言えない孤獨(dú)を抱えたまま1人で泣いてた","[00:28.040]":"誰にも上手に笑えない僕ら 2人出會って笑った","[00:39.710]":"","[00:40.410]":"真夜中過ぎに 想像の奧に","[00:46.150]":"どうしようもない気持ちをただ押しやって","[00:50.780]":"","[00:51.480]":"サヨナラ 僕らはきっと生まれ変われるから","[00:57.030]":"悲しみに手を振るんでしょう","[01:01.190]":"そしていつか 空っぽのままの心に燈りをともすように","[01:08.630]":"とぎれとぎれの 言葉を探して繋ぎ止めた","[01:14.390]":"それでもたった二人の世界は続いて行くんだ","[01:20.190]":"空に祈るように どうか永遠(yuǎn)に","[01:29.380]":"","[01:43.670]":"白?黒?壱?零 僕らは選ぶ事を迫られてばかり","[01:54.940]":"そうして殘った大事な物を壊れるほど抱きしめていた","[02:06.670]":"","[02:07.670]":"明け方過ぎの光の先に","[02:13.530]":"ほんの少しだけ未來が見えた気がして","[02:18.110]":"","[02:18.810]":"バカげた夢だってきっと願い続けるから","[02:24.330]":"奇跡に近づくんでしょう","[02:28.590]":"それは君の弱さの隣に見つけた強(qiáng)さの欠片だって","[02:36.160]":"とぎれとぎれの 言葉を探して繋ぎ止めた","[02:41.700]":"瞼の奧に滲んだ世界を守ってゆくんだ","[02:47.470]":"空に祈るように 君と誓う明日","[02:58.720]":"","[03:08.900]":"不自由な思いが重なり合ったら","[03:14.390]":"そうさ誰より自由になれた","[03:20.390]":"足りないものを埋め合うように","[03:25.700]":"疑いもせず 支えあいながら","[03:31.610]":"","[03:34.060]":"サヨナラ 僕らはきっと生まれ変われるから","[03:39.490]":"悲しみに手を振るんでしょう","[03:44.450]":"そしていつか 空っぽのままの心に燈りをともすように","[03:51.620]":"とぎれとぎれの 言葉を探して繋ぎ止めた","[03:57.190]":"それでもたった二人の世界は続いて行くんだ","[04:03.000]":"空に祈るように どうか永遠(yuǎn)に…"};var lrcTime = [];//歌詞對應(yīng)的時(shí)間數(shù)組var ul = $("#lrclist")[0];//獲取ulvar i = 0;$.each(lrcJSON, function(key, value) {//遍歷lrclrcTime[i++] = parseFloat(key.substr(1,3)) * 60 + parseFloat(key.substring(4,10));//00:00.000轉(zhuǎn)化為00.000格式ul.innerHTML += "<li><p>"+lrcJSON[key]+"</p></li>";//ul里填充歌詞});lrcTime[lrcTime.length] = lrcTime[lrcTime.length-1] + 3;//如不另加一個(gè)結(jié)束時(shí)間,到最后歌詞滾動不到最后一句var $li = $("#lrclist>li");//獲取所有l(wèi)ivar currentLine = 0;//當(dāng)前播放到哪一句了var currentTime;//當(dāng)前播放的時(shí)間var audio = document.getElementById("audio");var ppxx;//保存ul的translateY值audio.ontimeupdate = function() {//audio時(shí)間改變事件currentTime = audio.currentTime;for (j=currentLine, len=lrcTime.length; j<len; j++){if (currentTime<lrcTime[j+1] && currentTime>lrcTime[j]){currentLine = j;ppxx = 250-(currentLine*32);ul.style.transform = "translateY("+ppxx+"px)";$li.get(currentLine-1).className="";console.log("on"+currentLine);$li.get(currentLine).className="on";break;}}};audio.onseeked = function() {//audio進(jìn)度更改后事件currentTime = audio.currentTime;console.log(" off"+currentLine);$li.get(currentLine).className="";for (k=0, len=lrcTime.length; k<len; k++){if (currentTime<lrcTime[k+1] && currentTime<lrcTime[k]){currentLine = k;break;}}};</script></body> </html> 可能會有點(diǎn)不足之處,還望大佬們指正?
?
總結(jié)
以上是生活随笔為你收集整理的js解析lrc 实现lrc歌词同步滚动效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: android歌词同步源码,Androi
- 下一篇: 【MFC】MFC基础类——CString
