用JS解析LRC格式的歌词

1、把歌词载入。

方法一:直接把歌词粘贴到一个textarea文本域中,然后把它设置为隐藏。

<!-- LRC歌词 -->
<textarea id="lrc_content" cols="30" style="display: none">
[ti:沙漠骆驼]
[ar:展展与罗罗]
[al:沙漠骆驼]
[by:0]
[offset:0]
[00:00.59]沙漠骆驼 - 展展与罗罗
[00:02.97]词:展展与罗罗
[00:04.46]曲:展展与罗罗
[00:26.45]我要穿越这片沙漠
[00:28.51]找寻真的自我
[00:30.50]身边只有一匹骆驼陪我
[00:34.96]这片风儿吹过
[00:37.15]那片云儿飘过
[00:39.26]突然之间出现爱的小河
[00:43.63]我跨上沙漠之舟
[00:45.71]背上烟斗和沙漏
[00:47.92]手里还握着一壶烈酒
[00:52.35]漫长古道悠悠
[00:54.51]说不尽喜怒哀愁
[00:56.56]只有那骆驼奔忙依旧
[01:01.08][02:23.81][04:13.30]什么鬼魅传说
[01:03.12][02:25.94][04:15.20]什么魑魅魍魉妖魔
[01:05.43][02:28.30][04:17.47]只有那鹭鹰在幽幽的高歌
[01:09.81][02:32.61][04:21.83]漫天黄沙掠过
[01:11.90][02:35.04][04:23.90]走遍每个角落
[01:14.05][02:36.99][04:26.20]行走在无尽的苍茫星河
[01:18.69][02:41.50][04:30.60]白天黑夜交错
[01:20.80][02:43.56][04:32.65]如此妖娆婀娜
</textarea>

再用JS把歌词读出来:

<script>var lrc = document.getElementById("lrc_content").innerHTML;
</script>

方法二:用Ajax把后台的lrc文件载入。

var lrc = "";
function getLRC() {var ajax = new XMLHttpRequest();ajax.open("GET", "media/沙漠骆驼 - 展展与罗罗.lrc");ajax.onreadystatechange = function () {if (ajax.readyState == 4 && ajax.status == 200) {lrc = ajax.responseText;//console.log(lrc);createLrcObj(lrc); // 调用createLrcObj函数,并传入lrc参数}};ajax.send(null);
}
getLRC();

2、把LRC歌词解析为JS对象

代码如下:

var oLRC = {ti: "", //歌曲名ar: "", //演唱者al: "", //专辑名by: "", //歌词制作人offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置ms: [] //歌词数组{t:时间,c:歌词}
};function createLrcObj(lrc) {if(lrc.length==0) return;var lrcs = lrc.split('\n');//用回车拆分成数组for(var i in lrcs) {//遍历歌词数组lrcs[i] = lrcs[i].replace(/(^\s*)|(\s*$)/g, ""); //去除前后空格var t = lrcs[i].substring(lrcs[i].indexOf("[") + 1, lrcs[i].indexOf("]"));//取[]间的内容var s = t.split(":");//分离:前后文字if(isNaN(parseInt(s[0]))) { //不是数值for (var i in oLRC) {if (i != "ms" && i == s[0].toLowerCase()) {oLRC[i] = s[1];}}}else { //是数值var arr = lrcs[i].match(/\[(\d+:.+?)\]/g);//提取时间字段,可能有多个var start = 0;for(var k in arr){start += arr[k].length; //计算歌词位置}var content = lrcs[i].substring(start);//获取歌词内容for (var k in arr){var t = arr[k].substring(1, arr[k].length-1);//取[]间的内容var s = t.split(":");//分离:前后文字oLRC.ms.push({//对象{t:时间,c:歌词}加入ms数组t: (parseFloat(s[0])*60+parseFloat(s[1])).toFixed(3),c: content});}}}oLRC.ms.sort(function (a, b) {//按时间顺序排序return a.t-b.t;});/*for(var i in oLRC){ //查看解析结果console.log(i,":",oLRC[i]);}*/
}createLrcObj(lrc);

解析后的歌词位于oLRC对象的ms数组中:
oLRC.ms[i].t 是第i行歌词的时间,以秒计;
oLRC.ms[i].c 是第i行歌词。

3、把解析后的歌词呈现在页面上

定义一个列表标签:

<ul id="lyric"></ul>

用JS把歌词写到标签里面:

function showLRC() {var s="";for(var i in oLRC.ms){//遍历ms数组,把歌词加入列表s+='<li>'+oLRC.ms[i].c+'</li>';}document.getElementById("lyric").innerHTML = s;
}
showLRC();

以上完毕。

以下是结合这个页面加工后的完整代码:https://blog.csdn.net/yzy_csdn/article/details/84536646

<!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>带歌词歌曲</title><script src="../js/jquery-1.12.4.js"></script><style>/* https://blog.csdn.net/yzy_csdn/article/details/84536646 */div{width:340px;height:50px;margin:0 auto;overflow:hidden;}ul{transition-duration: 600ms;}ul, li{list-style:none;padding: 0;margin: 0;}.aplayer-lrc-contents li.on{color: #0e90d2;}.aplayer-lrc-contents li 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;}.aplayer-lrc:after,.aplayer-lrc:before {position: absolute;z-index: 1;display: block;overflow: hidden;content: ' ';width: 100%}.aplayer-lrc:before {top: 25px;height: 4%;background: -webkit-linear-gradient(top,#fff 0,rgba(255,255,255,0) 100%);background: -webkit-gradient(linear,left top,left bottom,from(white),to(rgba(255,255,255,0)));background: linear-gradient(to top,#fff 0,rgba(255,255,255,0) 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#00ffffff', GradientType=0 )}/*.aplayer-lrc:after {*//*bottom: 0;*//*height: 33%;*//*background: -webkit-linear-gradient(bottom,#fff 0,rgba(255,255,255,0) 100%);*//*background: -webkit-gradient(linear,left bottom,left top,from(white),to(rgba(255,255,255,0)));*//*background: linear-gradient(to top,#fff 0,rgba(255,255,255,0) 100%);*//*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff', GradientType=0 )*//*}*/</style></head><body><div class="aplayer-lrc"><ul id="lrclist" class="aplayer-lrc-contents" style="transform: translateY(0px);"><!-- 保证歌词在正中间 --></ul></div><audio id="audio" src="music/找一个字代替.mp3" controls="controls" autoplay></audio><script>var lrc = "";function getLRC() {var ajax = new XMLHttpRequest();ajax.open("GET", "lrc/找一个字代替.lrc");ajax.onreadystatechange = function () {// if (ajax.readyState === 4 && ajax.status === 200) {//     lrc = ajax.responseText;//     // document.getElementById("lyric1").innerHTML = lrc;//     createLrcObj(lrc);// }// if (ajax.readyState !== 4 && ajax.status === 404) {//     console.log(ajax.status);//     document.getElementById("lrclist").innerHTML = "<li class='on'><p>"+"暂无歌词"+"</p></li>";//     // ul.innerHTML += "<li><p>"+"暂无歌词"+"</p></li>";//ul里填充歌词// }// 判断响应是否完成:XMLHttpRequest 对象的 readystate属性值为4的时候if ( ajax.readyState === 4 ) {//再判断是否可用 :XMLHttpRequest 对象的 status 属性为值 200if ( ajax.status === 200 ) {lrc = ajax.responseText;createLrcObj(lrc);} else {document.getElementById("lrclist").innerHTML = "<li class='on'><p>"+"暂无歌词"+"</p></li>";}}};ajax.send(null);}getLRC();var oLRC = {ti: "", //歌曲名ar: "", //演唱者al: "", //专辑名by: "", //歌词制作人offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置ms: [] //歌词数组{t:时间,c:歌词}};function createLrcObj(lrc) {if (lrc.length === 0) return;var lrcs = lrc.split('\n');//用回车拆分成数组for (var i in lrcs) {//遍历歌词数组if (lrcs.hasOwnProperty(i)) {lrcs[i] = lrcs[i].replace(/(^\s*)|(\s*$)/g, ""); //去除前后空格var t_lrc = lrcs[i].substring(lrcs[i].indexOf("[") + 1, lrcs[i].indexOf("]"));//取[]间的内容var s_text = t_lrc.split(":");//分离:号前后的文字if (isNaN(parseInt(s_text[0]))) { //不是数值,基本上是歌曲名、作者等信息for (var j in oLRC) {if (j !== "ms" && j === s_text[0].toLowerCase()) {oLRC[j] = s_text[1];}}} else { //是数值,基本上就是歌词时间点var arr = lrcs[i].match(/\[(\d+:.+?)\]/g);//提取时间字段,可能有多个var start = 0;for (var lrc_position in arr) {if (arr.hasOwnProperty(lrc_position)) {start += arr[lrc_position].length; //计算歌词位置}}var content = lrcs[i].substring(start);//获取歌词内容for (var k in arr) {if (arr.hasOwnProperty(k)) {var t = arr[k].substring(1, arr[k].length - 1);//取[]间的内容var s = t.split(":");//分离:前后文字oLRC.ms.push({//对象{t:时间,c:歌词}加入ms数组t: parseFloat(s[0].substr(0,2)) * 60 + parseFloat(s[1].substring(0,6)),//注意转换成number格式// t: (parseFloat(s[0]) * 60 + parseFloat(s[1])).toFixed(3),c: content});}}}}}oLRC.ms.sort(function (a, b) {//按时间顺序排序return a.t - b.t;});// var lrc_result = "";var lrcTime = [];//歌词对应的时间数组var ul = $("#lrclist")[0];//获取ulfor (var n in oLRC.ms) {//遍历ms数组,把歌词加入列表// lrc_result += '<li>' + oLRC.ms[n].c + '</li>';// document.getElementById("lyric").innerHTML = lrc_result;ul.innerHTML += "<li><p>"+oLRC.ms[n].c+"</p></li>";//ul里填充歌词}// console.log(oLRC.ms[0].t); // 时间00:00.231中的0.231// console.log(oLRC.ms.length);// for(var result in oLRC){ //查看解析结果//     // console.log(result,":",oLRC[result]);// }for(var x=0;x< oLRC.ms.length; x++){lrcTime[x] = oLRC.ms[x].t;}lrcTime[oLRC.ms.length] = lrcTime[oLRC.ms.length-1] + 3;//如不另加一个结束时间,到最后歌词滚动不到最后一句var $li = $("#lrclist>li");//获取所有livar currentLine = 0;//当前播放到哪一句了var currentTime;//当前播放的时间var audio = document.getElementById("audio");var ppxx;//保存ul的translateY值audio.ontimeupdate = function() {//audio时间改变事件currentTime = audio.currentTime;for (j=currentLine, len=lrcTime.length; j<len; j++){ // len=50if (currentTime<lrcTime[j+1] && currentTime>lrcTime[j]){currentLine =  j;// ppxx = 250-(currentLine*32);ppxx = -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进度更改后事件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>

效果:

用JS解析LRC格式的歌词,实现歌词同步滚动效果相关推荐

  1. 用JS解析LRC格式的歌词

    用JS解析LRC格式的歌词 1.把歌词载入. 方法一:直接把歌词粘贴到一个textarea文本域中,然后把它设置为隐藏. <!-- LRC歌词 --> <textarea id=&q ...

  2. js解析lrc 实现lrc歌词同步滚动效果

    这两天想着做一个h5的网页播放器,实现歌词同步滚动 但是上网找了很多资料,竟发现没有比较完善的代码供参考,但是无意间看到了百度的千千音乐有这样的效果,就想着一定能通过js实现 经过两三天的努力,终于做 ...

  3. vue项目:歌词随歌曲同步滚动

    封装成对象,暴露出去共享使用 1.新建js文件 2.因为需要用到元素运动来实现歌词自上而下滚动的效果,又不想引用jquery增大js的加载,所有在对象内部封装了一个运动函数. 3.主要的函数是添加定时 ...

  4. vue实现歌词随音乐同步滚动

    请求回来的歌词是以下格式 第一步先处理歌词 if (this.lyricList.lyric) { //判断有没有歌词,因为有些音乐没有歌词arr = this.lyricList.lyric.spl ...

  5. android开发歌词滑动效果_Android 歌词同步滚动效果

    歌词是播放器类App必不可少的组件,而一般的歌词组件都需要做到歌词的显示与播放进度同步.我们知道,歌词是如下所示的文件: lrc [ti:原来爱情这么伤] [ar:梁咏琪] [al:给自己的情歌] [ ...

  6. iOS 歌词解析(lrc, 非谓词, 仿QQ音乐, 仿卡拉ok模式)

    前言 要解析 lrc 格式的歌词, 首先需要知道什么是 lrc 歌词, 还需要知道 lrc 歌词的规范. 在这里先放出一个百度百科的链接地址, 仅供大家参考: 百度百科: lrc 关于本文 本文的歌词 ...

  7. PCB javascript解析Gerber274X格式实现方法

    解析钻Gerber274X格式前首先得了解此格式,这样才能更好的解析呀. 一个Gerber274X里面包含的基本信息如下: 1.单位:公式mm,英制inch 2.省零方式:前省零,后省零 3.坐标方式 ...

  8. js 停顿一秒_JS实用的带停顿的逐行文本循环滚动效果实例

    如下所示: JS实用的带停顿的逐行文本循环滚动效果 #scrollBox2{font-size:12px;width:260px;color:#646464;line-height:22px;heig ...

  9. JS解析提取LRC格式的歌词

    解析提取lrc格式的歌词 参考:https://blog.csdn.net/fenglin247/article/details/86674646 [ar:王菲] [ti:匆匆那年] [00:00.5 ...

最新文章

  1. Postman系列之@RequestBody修饰的对象传参数
  2. 图像色彩空间与应用转换
  3. python 类的特殊属性、特殊方法 __str__,__bases__,__mor__,__add__,__call__
  4. Rhel6服务器时间任务浅谈
  5. 微软的公开的DLL库
  6. 强化学习—— 经验回放(Experience Replay)
  7. pdfbox创建pdf_PDFBox创建PDF文档
  8. Python:Tensorflow中两个稀疏张量相乘
  9. Python与数据库(1)mysql
  10. win7的centos虚拟机上搭建mysql5.6服务
  11. C++基础:第五章 表达式基础与详述
  12. 一个websocket 可以多个页面创建吗_聊聊 WebSocket,还有 HTTP
  13. 计算机教室所有计算机无法启动,多媒体教室常见故障及解决方法
  14. 美图秀秀去广告单文件版 v6.4.3.0
  15. jenkins with ant 和 invoke ant
  16. Linux Mint 19 Tara x86_64安装Docker-ce
  17. Spring Cloud (四):断路器(Hystrix)
  18. 助眠好物推荐,改善睡眠的好方法
  19. 把Swing的Icon转换到SWT的Image
  20. 期货交易的安全性分析

热门文章

  1. 公网搭建Kubernetes 1.20.9(阿里云+腾讯云)
  2. 项目经理人如何做好目标管理?
  3. 常用的linux桌面环境有,推荐!5款Linux常用桌面环境
  4. mysql buff cache_Linux中buff/cache内存占用过高解决办法
  5. 高考:三本,计算机专业的建议
  6. 查看主机IP端口与快解析的内网映射
  7. 为什么你有10年经验,但成不了专家?
  8. 行人重识别0-00:DG-Net(ReID)-目录-史上最新无死角讲解
  9. C#上位机开发常遇问题
  10. 犀牛脚本插件-获取选择对象长度-Python-几何对象长度-rhino脚本