【黑师音画帖小白教程】第二十七讲:在帖子中实现LRC歌词同步

位置: 首页 > 马黑教程
[发布: 2024.8.28  作者: 马黑  阅读: 88]

第二十七讲:在帖子中实现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条]

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