【黑师音画帖小白教程】第二十七讲:在帖子中实现LRC歌词同步
第二十七讲:在帖子中实现LRC歌词同步
LRC歌词同步在帖子中的实现离不开CSS和JS的加持,CSS主要负责包含动画在内的歌词界面的定制、JS侧重管理和驱动歌词的动态变化。本讲主要讲讲实现原理,以及如何通过使用插件来实现LRC歌词同步。
先简单说说实现LRC歌词同步的原理:使用元素+伪元素分别装载当前演唱的同一句歌词,宿主元素装载的是偏暗或偏灰的歌词,伪元素则装载亮色的歌词并令其宽度从0变到100%。以下是一个模拟性质的演示实例:
<style> .lrcBox { width: fit-content; /* 自适应宽度 :根据文本决定 */ height: 40px; font: bold 20px/40px sans-serif; /* 行高与盒子高度一致以保证文本垂直居中 */ color: silver; /* 歌词底色 */ white-space: pre; /* white-space属性用于控制折行行为 */ padding: 10px; border: 1px solid; position: relative; /* 父元素相对或绝对定位均可 */ } .lrcBox::before { position: absolute; /* 伪元素必须绝对定位 */ content: attr(data-text); /* 伪元素文本使用CSS函数 attr(变量名) */ overflow: hidden; /* 必须设定防止溢出属性为hidden隐藏 */ width: 0; /* 开始时宽度是 0 */ height: 100%; /* 高度是父元素的100% */ color: red; /* 歌词同步颜色 */ transition: 3s; /* transition动画周期时长 */ } /* 伪元素通过伪类属性运行transition动画 */ .lrcBox:hover::before { width: 100%; /* 宽度变为 100% */ } </style> <div class="lrcBox" data-text="LRC歌词演示 : 鼠标移入移出看效果">LRC歌词演示 : 鼠标移入移出看效果</div>
上面演示的示例没有JS代码的参与,仅通过CSS的 transition 动画加以模拟,通过元素的伪类选择器 :hover 触发,意在展示歌词同步的原理。真正要实现歌词同步时,我们将使用CSS的 @keyframes 属性设计动画并通过元素的 animation 属性运行动画,JS要做的事情则是一个庞大而细致的工作,如果代码都放在帖子里,那帖子的代码量可能会大得惊人,因此,JS代码应该封装成插件或其他资源,帖子里仅需引用和配置插件或资源即可。本人写有一些lrc歌词同步的播放器插件,有基于精准同步的花潮lrc歌词格式和基于不那么精准同步的原生LRC歌词同步两种类型,前者需要单独制作歌词,后者可以使用现成的LRC歌词。有些歌如果找不到合适的元素lrc歌词也可以自己制作,如果手头没有制作软件,可以使用本人配套插件而开发的《原生lrc在线制作工具》制作lrc歌词。讲义推荐使用原生lrc歌词同步播放器插件,至于花潮格式精准同步插件感兴趣的童鞋可以访问 《HCPlayer插件汇总》 学习了解。下面就说说原生LRC歌词同步播放器插件的引用和配置。
一、了解原生LRC歌词结构与歌词声明
专业的LRC歌词结构略微有些复杂,这里只谈谈插件支持的基本结构。很简单:
/* LRC歌词每句歌词的结构如下: [mm:ss.xx(x)]歌词 其中,中括号里面是时间信息,注意连接符 : 和 . : mm 分,二位数,例 00 或 02 ss 秒,二位数,例 06 或 56 xx(x) 毫秒,二或三位数,例 80 或 954 下面是帖子JS代码中声明歌词变量的方法,注意反引号的使用, 其作用主要是歌词信息可以分行写、支持歌词中出现小角引号 */ /* 方法一:连着写,用 \n 连接各句歌词 */ var lrcText = `[00:00.351]歌词1\n[00:01.926]歌词2\n[00:26.654]……\n[03:45.442]歌词N\n`; /* 方法二:歌词分行写(必须使用反引号包裹歌词) */ var lrcText = ` [00:00.351]歌词1 [00:01.926]歌词2 [00:26.654]…… [03:45.442]歌词N `;
二、引用LRC歌词同步播放器插件
不同的插件引用的方法都一样。下面以圆环斜频谱插件为例加以说明:
/* JS代码 :论坛发帖引用播放器插件代码 */ var sf = document.createElement('script'); sf.charset = 'utf-8'; sf.src = 'https://638183.freep.cn/638183/web/js2024/pinpux_yslrc.js'; document.body.appendChild(sf);
这其实是给页面追加 script 标签:先声明 sf 变量用来存储待创建的 script 标签对象,标签的字符集为 UTF-8 以避免英文以外的字符出现乱码,标签的 src 属性(属于HTML属性)即为插件的地址,然后将创建好的 script 标签追加给页面的 body 标签,body 是页面中的大容器标签,俗称老大,是web页现实意义上辈分最高的父元素,不过它之上还有html标签,是web页总集团董事长,body对总集团来说只是一个相当重要的基层单位,但body对web页要呈现的内容来说是大部门的老总。
三、配置插件
在论坛,插件的配置需要配套插件的加载,只有插件加载完毕所做的配置才会生效。上面的 sf 对象变量因此在做插件配置时还会用到,sf.onload({...}),即 sf 这个script标签对象加载完毕时在 ... 处配置插件:
/* JS代码 :配置插件 sf加载完毕操作配置 */ sf.onload = () => { /* 配置开始 : HCPlayer({ ... }); 是插件通用配置结构 */ HCPlayer({ papa: '#mydiv', /* 指定帖子元素选择器 */ geci: lrcText, /* 指定歌词变量 : 变量名与歌词声明的变量要相一致 */ pinpu: { num: 40, color: 'linear-gradient(orange, transparent, orange)' }, /* 频谱设置 */ lrc_css: `left: 20%; top: 30px; `, /* LRC歌词CSS设置 */ player_css: `right: 60px; bottom: 20px;`, /* 播放器CSS设置 */ fs_css: `left: 30px; bottom: 20px;`, /* 全屏按钮CSS设置 */ }); }; /* 下面是最简单的配置,这意味着一切使用插件默认的参数值 */ sf.onload = () => HCPlayer({papa: '#mydiv'});
所有插件的配置一定不能少的是 papa 参数,不过不见得是靠谱的配置,事实上,一切应根据帖子的设计配置插件。不同的插件,配置参数不尽一致,但都用共性,例如 papa 参数、geci 参数、lrc_css 参数、player_css 参数、fs_css 参数等等,每一个插件都会有,其中参数名为 *_css 的参数都是基于CSS的参数,建议使用反引号 `` 将参数值包裹起来,这样里面的每一个CSS属性都可以分行写;而像上例的 pinpu 参数,其值使用花括号 {} 包裹,是插件定义的频谱对象参数,键值对之间用小角逗号隔开,天然地支持分行写各个键值对,要注意的是,对象参数值中的键值值如果是字符串必须使用小角引号包裹。插件提供的参数,以及参数值的子项目,不便在此一一说明,可以访问《原生lrc歌词同步插件列表》,找到自己希望使用的插件,里面有每一个插件的说明和示例链接,研究好之后再使用。
顺便提一下,上面代码中,绿色文本为注释文本,熟悉了代码意义之后,做帖时可以不要这些注释。
前面提到过,花潮格式的LRC歌词同步更为精准,这是因为本人设计的歌词结构包含了每一句歌词的具体演唱用时。依此道理,原生LRC歌词如果不太准确也可以略作改造,弄得好也可以达到相对精准的同步效果:一是给间隔过长的两句歌词间加一个时间+额外的相关信息或干脆歌词留空也行,以压缩它们的间隔;二是给出合适的 average 参数值,它可以抵消一些不合理的间隔,但确定参数值的难度较大,一般的判断依据是歌词的起唱、中间过渡、末尾止唱是否存在较大间隔的无歌词过程,它们与大概的各句歌词的平均用时是否存在较大的偏差等等,这些可能需要操作上的经验。
最后给出一个简单的使用原生LRC歌词同步播放器的示例,以结束本讲的讲义:
<style> #tz { width: 740px; height: 350px; background: linear-gradient(lightblue, black); position: relative; } </style> <div id="tz"> <audio src="https://music.163.com/song/media/outer/url?id=1363152402" loop autoplay></audio> </div> <script> var lrcStr = ` [00:00.952]纯音乐 - 凡尘 [00:20.126]歌手 - 九鸢Pro [00:26.102] `; var sf = document.createElement('script'); sf.charset = 'utf-8'; sf.src = 'https://638183.freep.cn/638183/web/js2024/pinpux_yslrc.js'; document.body.appendChild(sf); sf.onload = () => { HCPlayer({ papa: '#tz', geci: lrcStr, pinpu: { num: 20, }, }); }; </script>
作业:参照本讲最后一个示例,挑选一个中意的插件,制作一个真正的LRC歌词同步帖子。要求帖子要有背景图片,并能根据需要调整歌词、播放器和全屏按钮的位置和颜色。作业主要目的是尝试使用插件,因此帖子漂亮与否不是重点,重点在驾驭插件,让插件为己所用。
前一篇: 【黑师音画帖小白教程】第二十六讲:学一点点JS(六)JS操作CSS变量
下一篇: 【黑师音画帖小白教程】第二十八讲:帖子子元素布局技巧(一)
评论列表 [0条]