马黑PHP整站系统

实现原生lrc歌词同步之超级简化版

位置: 首页 > 前端三套件[ 发布时间: 2024.6.18  作者: 马黑  阅读: 257 ]

先看原生lrc歌词的解析,我创建了一个函数,全程仅用10行代码将歌词转换成花潮格式的lrc歌词数组:

var lrcAr = [];   var getLrcAr = (text) => {     var ar = text.trim().split('\n');     ar.sort();     var reg = /\[(\d+)[.:](\d+)[.:](\d+)\](.*)/;     ar.forEach(item => {         let result = item.match(reg);         let tmsg = parseInt(result[1]) * 60 + parseInt(result[2]) + parseInt(result[3]) / 1000;         lrcAr.push([tmsg, result[4].trim()]);     }); };

函数所需参数 text 是原生lrc歌词字符串。函数先将歌词去除头尾空白后按行拆分为数组并进行排序,然后逐行按正则进行解析、提取所需信息再加入事先声明的全局数组变量 lrcAr。正则表达式的设计是简化处理机制的关键,代码中 reg 变量值是一个正则,它分成四个提取组,匹配成功后将拿到5个数组元素的结果,后四个对应于分、秒、毫秒和歌词。

传参执行函数,拿到的结果是花潮格式的lrcAr数组,这意味着众多歌词同步的插件可以派上用场了。

需要注意的是:

一、支持的原生lrc歌词格式

① [mm:ss:ff]歌词
② [mm:ss.ff]歌词
③ [mm.ss.ff]歌词
④ [mm.ss:ff]歌词

前两种较为常见,后两种偶尔会见到。这些格式的原生lrc歌词,可以混合出现在歌词中,函数都能处理。

二、不支持复合时间信息原生lrc歌词格式,例如下面这两种:

① [mm:ss:ff][mm:ss:ff]歌词
② [mm:ss:ff][mm:ss:ff][mm:ss:ff]歌词

如果碰上这类结果的复合时间信息的歌词,请手动将其分开(歌词相同),顺序不用管。

三、原生歌词的写法

可以分行写,一行一句;也可以使用分隔符 \n 衔接各句歌词。例如:

最后给出一个应用实例,无插件依赖。代码:

<style> #tz { margin: 20px auto; width: 740px; height: 300px; border: 1px solid gray; position: relative; } #tz::before { content: attr(data-lrc); position: absolute; bottom: 0; width: 100%; height: 60px; text-align: center; font: normal 24px/60px sans-serif; color: transparent; background: repeating-linear-gradient(to right, red, green, blue, green, red) 50%/200px 60px; -webkit-background-clip: text; } #player { position: absolute; top: 30px; left: calc(50% - 61px); cursor: pointer; animation: rot 6s linear infinite var(--state); } @keyframes rot { to { transform: rotate(360deg); } } </style>   <div id="tz" data-lrc="HUACHAO">     <audio id="aud" src="https://music.163.com/song/media/outer/url?id=1429962105" autoplay loop></audio>     <img id="player" src="https://638183.freep.cn/638183/t23/btn/plum.png" alt="" title="播放/暂停" /> </div>   <script> var curkey = 0, lrcAr = []; var getAr = (text) => {     var ar = text.trim().split('\n');     ar.sort();     var reg = /\[(\d+)[.:](\d+)[.:](\d+)\](.*)/;     ar.forEach(item => {         let result = item.match(reg);         let tmsg = parseInt(result[1]) * 60 + parseInt(result[2]) + parseInt(result[3]) / 1000;         lrcAr.push([tmsg, result[4].trim()]);     }); }; var mState = () => {     tz.style.setProperty('--state', ['running','paused'][+aud.paused]);     player.title = ['暂停','播放'][+aud.paused];     //其它控制代码 }; aud.onseeked = () => curkey = 0; aud.onplaying = aud.onpause = () => mState(); aud.ontimeupdate = () => {     if(curkey > lrcAr.length - 1) return;     if(aud.currentTime >= lrcAr[curkey][0]) {         tz.dataset.lrc = lrcAr[curkey][1];         curkey ++;     } }; player.onclick = () => aud.paused ? aud.play() : aud.pause(); var lrc = ` [00:00:900]张子铭 - 一生最爱 [00:20.180]向雪怀作词,伍思凯作曲 [00:22.180]吉他:白毛 [00:23.678]如果痴痴的等某日终于可等到一生中最爱 [00:31.426]谁介意你我这段情每每碰上了意外不清楚未来 [00:38.678]何曾愿意 我心中所爱 [00:45.927]每天要孤单看海 [00:54.426]宁愿一生都不说话都不想讲假说话欺骗你 [01:02.177]留意到你我这段情你会发觉间隔着一点点距离 [01:09.426]无言地爱 我偏不敢说 [01:17.676]说一句想跟你一起 [01:24.427]OOOH OOH [01:28.926]如真 如假 如可分身饰演自己 [01:36.674]会将心中的温柔献出给你唯有的知己 [01:44.174]如痴 如醉 还盼你懂珍惜自己 [01:51.675]有天即使分离我都想你我 真的想你 [02:27.172]宁愿一生都不说话都不想讲假说话欺骗你 [02:35.172]留意到你我这段情你会发觉间隔着一点点距离 [02:42.423]无言地爱 我偏不敢说 [02:50.671]说一句想跟你一起 [02:57.424]OOOH OOH [03:01.922]如真 如假 如可分身饰演自己 [03:09.422]会将心中的温柔献出给你唯有的知己 [03:17.171]如痴 如醉 还盼你懂珍惜自己 [03:24.671]有天即使分离我都想你我 真的想你 [03:36.422]如真 如假 如可分身饰演自己 [03:43.922]会将心中的温柔献出给你唯有的知己 [03:51.670]如痴 如醉 还盼你懂珍惜自己 [03:59.421]有天即使分离我都想你我 真的想你 [04:11.674]如果痴痴的等某日终于可等到一生中最爱 `; getAr(lrc); </script>

前一篇: 不改变文档结构实时渲染彩虹字
下一篇: CSS关键帧动画文本效果:逐行出场

发表评论:

       

评论列表 [3条]

#3 | 小希 于 2024-6-18 21:43 发布: 刚试了一曲,找到同曲,歌词直接复制入代码。。。真实感受,快。。

#2 | 飞飞 于 2024-6-18 21:42 发布: 这个真是太棒了,要省好多事啊。。。https://www.90lrc.cn/这个原生歌词网站~

#1 | 悄然 于 2024-6-18 12:45 发布: 这个好方便,借老师整好的歌词跟一个贴子:)速成的

Copyright © 2023 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com