900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 用JS实现歌词与播放音乐同步

用JS实现歌词与播放音乐同步

时间:2019-12-17 08:32:08

相关推荐

用JS实现歌词与播放音乐同步

用JS实现歌词与播放音乐同步

第一步:把歌词解析成JS对象

参看我的上一篇文章:用JS解析LRC格式的歌词

解析后的歌词写到页面的一个列表中,效果如下:

主要HTML代码:

<!-- 播放器 --><audio id="audio" src="media/沙漠骆驼 - 展展与罗罗.mp3" controls preload="auto"></audio><!-- 歌词 --><div class="lyric_area"><ul id="lyric"></ul></div>

CSS:

.lyric_area{/*歌词显示区域*/height: 300px; /*歌词区域高度*/overflow: hidden; /*隐藏超出部分*/margin-top: 15px;}#lyric{/*歌词列表*/line-height: 20px;/*行高,这个值要用在歌词滚动距离上*/transition-duration: 600ms;/*滚动速度*/}#lyric .lineHigh{/*高亮行*/color: red;}

第二步:播放音乐时让当前行高亮显示并向上滚动

解析后的歌词放在oLRC对象的ms数组中,呈现以下形态:

ms : [

{t: “0.590”, c: “沙漠骆驼 - 展展与罗罗”}

{t: “2.970”, c: “词:展展与罗罗”}

{t: “4.460”, c: “曲:展展与罗罗”}

{t: “26.450”, c: “我要穿越这片沙漠”}

{t: “28.510”, c: “找寻真的自我”}

{t: “30.500”, c: “身边只有一匹骆驼陪我”}

… …

]

ms[i].t是歌词的开始时间,ms[i].c是歌词内容。

现在歌词内容已经写在上面的<ul>列表中了,我们要做的是让高亮歌词与播放同步。

var lineNo: 0, //当前行var C_pos: 6, //C位var offset: -20, //滚动距离(应等于行高)var audio = document.getElementById("audio");//播放器var ul = document.getElementById("lyric"); //歌词容器列表//高亮显示歌词当前行及文字滚动控制,行号为lineNofunction lineHigh() {var lis = ul.getElementsByTagName("li");//歌词数组if(lineNo>0){lis[lineNo-1].removeAttribute("class");//去掉上一行的高亮样式}lis[lineNo].className = "lineHigh";//高亮显示当前行//文字滚动if(lineNo>C_pos){ul.style.transform = "translateY("+(lineNo-C_pos)*offset+"px)"; //整体向上滚动一行高度}}//滚回到开头,用于播放结束时function goback() {document.querySelector("#lyric .lineHigh").removeAttribute("class");ul.style.transform = "translateY(0)";lineNo = 0;}//监听播放器的timeupdate事件,实现文字与音频播放同步audio.ontimeupdate = function () {if(lineNo==oLRC.ms.length)return;var curTime = audio.currentTime; //播放器时间if(parseFloat(oLRC.ms[lineNo].t)<=curTime){lineHigh();//高亮当前行lineNo++;}};//监听播放器的ended事件,播放结束时回滚歌词audio.onended = function () {goback(); //回滚歌词};

歌词与播放同步的关键是从播放器获取当前时间,这需要监听audio对象的timeupdate事件,该事件在播放位置发生变化时触发,再从audio对象的currentTime属性中可取到当前播放时间。

滚动歌词使用的是CSS的变换函数transform:translateY(长度),它可以把歌词容器整体上移指定长度,由于容器外的div标签设置了overflow: hidden;,所以感觉歌词在向上滚动了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。