audio播放器对lrc歌词同步的实现思路
本帖最后由 马黑黑 于 2022-2-16 22:41 编辑这里假设我们已经把lrc歌词变成了我们的JS数组——
lrc歌词样式:
动身跋涉千里
追逐沿途的风景
经手动批量处理(Emeditor做这个事情再简单不过了),得出下面的JS二维数组样式:
["00:21.55","动身跋涉千里"],
["00:25.49","追逐沿途的风景"],
当然,以上的做法可以通过JS来完成,这个事将来再考虑,现在先来完成核心功能的部分。
先组织好lrc歌词数组(二维):
var lrcAr=[
["00:00.31","刘艺雯 - 听闻远方有你"],
["00:01.98","作词:刘钧"],
// ......
["03:52.52","只为你的温柔"]
];
这个数组里,每一个子项的第一个数组对应lrc歌词中的时间信息,我们需要将其转换成秒数,因为audio的当前播放时间以秒数呈现。我们的思路是,通过监听audio的当前播放时间,拿去与lrc歌词的时间进行比较,只要当前的播放时间大于lrc的某个时间节点,就显示它所对应的歌词,即JS数组中各子数组第二个数组元素。这样,lrc时间消息我们只需读取到 xx:yy 便可,也就是分和秒,毫秒忽略。下面就是我们定义的将lrc时间信息转换为秒数的函数:
//lrc时间信息转为秒
function toSec(lrcTime) {
let tmpAr = lrcTime.split(':');
lrcTime = tmpAr * 60 + parseInt(tmpAr);
return lrcTime;
}
这个函数需要一个事件参数 lrcTime,它就是 xx:yy 格式的lrc事件消息。我们通过符号 : 来拆分字符串,得到左边的分钟信息,它乘以60变成了秒数,右边的就是秒数,因为带有小数点,我们用 parseInt 内置函数将其强制变换为整数,然后将二者加起来并返回给调用者。
接下来调用上面这个函数将JS数组改装一下:
//处理lrc歌词数组:时间转换成秒
for(j=0; j<lrcAr.length; j++){
lrcAr = toSec(lrcAr);
//console.log(lrcAr, "-", lrcAr);//测试
}
这就差不多了,现在只缺少一个监听事件:
//audio监听事件
audio.ontimeupdate = function() {
let tt = audio.currentTime;
for(j=0; j<lrcAr.length; j++){
if(tt > lrcAr) console.log(tt, "-", lrcAr, "-", lrcAr);
}
}
监听事件(ontimeupdate)的匿名函数里,我们令 tt 获取 audio 的当前播放时间,将之放置在一个for循环里不断地与lrc歌词数组各子项的第一个数组比较,大于哪一个就在控制台中显示对应的歌词和其他信息。
下面是完整代码,我们的演示需要一个舞台和道具——audio和div标签:
<div id="lrcDiv" style="padding:10px; width:300px;height:30px;">歌词显示</div>
<audio id="myplayer" src="http://www.kumeiwp.com/sub/filestores/2022/01/31/12321664f29ec95b02bfbf62ddab082a.mp3" controls="controls" loop="loop"></audio>
<script language="javascript">
var lrcAr=[
["00:00.31","刘艺雯 - 听闻远方有你"],
["00:01.98","作词:刘钧"],
["00:03.04","作曲:刘钧"],
["00:04.18","编曲:刘钧"],
["00:17.67","听闻远方有你"],
["00:21.55","动身跋涉千里"],
["00:25.49","追逐沿途的风景"],
["00:29.13","还带着你的呼吸"],
["00:33.30","真的难以忘记"],
["00:37.17","关于你的消息"],
["00:41.11","陪你走过南北东西"],
["00:44.83","相随永无别离"],
["00:49.00","可不可以爱你"],
["00:52.71","我从来不曾歇息"],
["00:56.65","像风走了万里"],
["00:59.60","不问归期"],
["01:04.37","我吹过你吹过的风"],
["01:08.17","这算不算相拥"],
["01:12.18","我走过你走过的路"],
["01:15.97","这算不算相逢"],
["01:19.91","我还是那么喜欢你"],
["01:23.85","想与你到白头"],
["01:27.72","我还是一样喜欢你"],
["01:31.66","只为你的温柔"],
["02:07.40","听闻远方有你"],
["02:11.20","动身跋涉千里"],
["02:14.99","追逐沿途的风景"],
["02:18.70","还带着你的呼吸"],
["02:22.88","真的难以忘记"],
["02:26.82","关于你的消息"],
["02:30.77","陪你走过南北东西"],
["02:34.33","相随永无别离"],
["02:38.50","可不可以爱你"],
["02:42.37","我从来不曾歇息"],
["02:46.16","像风走了万里不问归期"],
["02:53.83","我吹过你吹过的风"],
["02:57.77","这算不算相拥"],
["03:01.71","我走过你走过的路"],
["03:05.57","这算不算相逢"],
["03:09.44","我还是那么喜欢你"],
["03:13.38","想与你到白头"],
["03:17.40","我还是一样喜欢你"],
["03:21.27","只为你的温柔"],
["03:25.30","我吹过你吹过的风"],
["03:29.01","这算不算相拥"],
["03:32.96","我走过你走过的路"],
["03:36.90","这算不算相逢"],
["03:40.76","我还是那么喜欢你"],
["03:44.70","想与你到白头"],
["03:48.49","我还是一样喜欢你"],
["03:52.52","只为你的温柔"]
];
var myaud = document.getElementById('myplayer'); //播放器标识
var lrcDiv = document.getElementById('lrcDiv'); //歌词显示div标识
//处理lrc歌词数组:时间转换成秒
for(j=0; j<lrcAr.length; j++){
lrcAr = toSec(lrcAr);
}
//lrc时间信息转为秒
function toSec(lrcTime) {
let tmpAr = lrcTime.split(':');
lrcTime = tmpAr * 60 + parseInt(tmpAr);
return lrcTime;
}
//同步显示歌词
myaud.ontimeupdate = function() {
let tt = myaud.currentTime;
for(j=0; j<lrcAr.length; j++){
if(tt > lrcAr) lrcDiv.innerHTML = lrcAr;
}
}
</script>
本帖最后由 马黑黑 于 2022-2-16 14:17 编辑 <br /><br /><div id="lrcDiv" style="padding:10px; width:300px;height:30px;">歌词显示</div>
<audio id="myplayer" src="http://www.kumeiwp.com/sub/filestores/2022/01/31/12321664f29ec95b02bfbf62ddab082a.mp3" controls="controls" loop="loop"></audio>
<script language="javascript">
var lrcAr=[
["00:00.31","刘艺雯 - 听闻远方有你"],
["00:01.98","作词:刘钧"],
["00:03.04","作曲:刘钧"],
["00:04.18","编曲:刘钧"],
["00:17.67","听闻远方有你"],
["00:21.55","动身跋涉千里"],
["00:25.49","追逐沿途的风景"],
["00:29.13","还带着你的呼吸"],
["00:33.30","真的难以忘记"],
["00:37.17","关于你的消息"],
["00:41.11","陪你走过南北东西"],
["00:44.83","相随永无别离"],
["00:49.00","可不可以爱你"],
["00:52.71","我从来不曾歇息"],
["00:56.65","像风走了万里"],
["00:59.60","不问归期"],
["01:04.37","我吹过你吹过的风"],
["01:08.17","这算不算相拥"],
["01:12.18","我走过你走过的路"],
["01:15.97","这算不算相逢"],
["01:19.91","我还是那么喜欢你"],
["01:23.85","想与你到白头"],
["01:27.72","我还是一样喜欢你"],
["01:31.66","只为你的温柔"],
["02:07.40","听闻远方有你"],
["02:11.20","动身跋涉千里"],
["02:14.99","追逐沿途的风景"],
["02:18.70","还带着你的呼吸"],
["02:22.88","真的难以忘记"],
["02:26.82","关于你的消息"],
["02:30.77","陪你走过南北东西"],
["02:34.33","相随永无别离"],
["02:38.50","可不可以爱你"],
["02:42.37","我从来不曾歇息"],
["02:46.16","像风走了万里不问归期"],
["02:53.83","我吹过你吹过的风"],
["02:57.77","这算不算相拥"],
["03:01.71","我走过你走过的路"],
["03:05.57","这算不算相逢"],
["03:09.44","我还是那么喜欢你"],
["03:13.38","想与你到白头"],
["03:17.40","我还是一样喜欢你"],
["03:21.27","只为你的温柔"],
["03:25.30","我吹过你吹过的风"],
["03:29.01","这算不算相拥"],
["03:32.96","我走过你走过的路"],
["03:36.90","这算不算相逢"],
["03:40.76","我还是那么喜欢你"],
["03:44.70","想与你到白头"],
["03:48.49","我还是一样喜欢你"],
["03:52.52","只为你的温柔"]
];
var myaud = document.getElementById('myplayer'); //播放器标识
var lrcDiv = document.getElementById('lrcDiv'); //歌词显示div标识
//处理lrc歌词数组:时间转换成秒
for(j=0; j<lrcAr.length; j++){
lrcAr = toSec(lrcAr);
}
//lrc时间信息转为秒
function toSec(lrcTime) {
let tmpAr = lrcTime.split(':');
lrcTime = tmpAr * 60 + parseInt(tmpAr);
return lrcTime;
}
//同步显示歌词
myaud.ontimeupdate = function() {
let tt = myaud.currentTime;
for(j=0; j<lrcAr.length; j++){
if(tt > lrcAr) lrcDiv.innerHTML = lrcAr;
}
}
</script>
外加提供的秒数,能跟音乐播放的秒数对应起来,这个功能{:4_199:} 本帖最后由 马黑黑 于 2022-2-16 14:48 编辑
附:用Emeditor将lrc歌词转换为JS数组的操作方法——
步骤一:将lrc歌词粘贴到Emeditor,把与歌词无关的头部消息去掉,仅保留有“时间+歌词”的内容;
步骤二:按 Ctrl + H 调出替换窗口,然后(所查找和替换的都是小角符号)——
① 确保不启用正则表达式,在查找处输入小角 [ ,在替换处输入一个小角 [ 和一个小角双引号 " ,即 [" ,点击“全部替换”;
② 在查找处输入小角中括号反(这里我输入老被吃掉) ,替换处输入"," ,点“全部替换”
③ 启用正则表达式,即点击“正则表达式”,在查找处输入 $ ,在替换处输入 "], ,点“全部替换”。
至此,文档变成这样的样式:
["00:00.31","刘艺雯 - 听闻远方有你"],
["00:01.98","作词:刘钧"],
["00:03.04","作曲:刘钧"],
["00:04.18","编曲:刘钧"],
["00:17.67","听闻远方有你"],
④ 我们加上JS数组的头尾,并把最后一行末尾处的逗号去掉即可大功告成:
var lrcAr=[
["00:00.31","刘艺雯 - 听闻远方有你"],
["00:01.98","作词:刘钧"],
["00:03.04","作曲:刘钧"],
["00:04.18","编曲:刘钧"],
["00:17.67","听闻远方有你"]
];
红影 发表于 2022-2-16 14:43
外加提供的秒数,能跟音乐播放的秒数对应起来,这个功能
手动制作JS歌词数组的方法看地板楼 “我们用 parseInt 内置函数将其强制变换为整数”
这个是直接舍去小数还是大于多少就进位? 红影 发表于 2022-2-16 14:44
“我们用 parseInt 内置函数将其强制变换为整数”
这个是直接舍去小数还是大于多少就进位?
parse是强制,Int是整数,强制转换成整数,没有小数点 马黑黑 发表于 2022-2-16 14:44
手动制作JS歌词数组的方法看地板楼
Emeditor加这些符号真方便{:4_204:} 马黑黑 发表于 2022-2-16 14:49
parse是强制,Int是整数,强制转换成整数,没有小数点
嗯,就是后面不管多大都舍去。 红影 发表于 2022-2-16 15:03
嗯,就是后面不管多大都舍去。
这思路其实挺经济(不用处理毫秒 ),也合理(歌词会提前省去的毫秒数出现) 马黑黑 发表于 2022-2-16 15:07
这思路其实挺经济(不用处理毫秒 ),也合理(歌词会提前省去的毫秒数出现)
遇到超过1小时的唱歌, 还要多加一组数据吧。
你之前的那个很多歌曲的那个,要是做歌词同步,要每个歌曲都嵌进去这个同步命令吧。 红影 发表于 2022-2-16 15:18
遇到超过1小时的唱歌, 还要多加一组数据吧。
你之前的那个很多歌曲的那个,要是做歌词同步,要每个歌 ...
这个我考虑过,数组不用加,但要处理一下小时数,把小时数变为秒数就可以了的 马黑黑 发表于 2022-2-16 16:11
这个我考虑过,数组不用加,但要处理一下小时数,把小时数变为秒数就可以了的
乘以3600. 红影 发表于 2022-2-16 20:54
乘以3600.
我数学不好,我不值得{:5_117:} 一个使用例子:单曲播放器+宽幅
https://www.huachaowang.com/forum.php?mod=viewthread&tid=57079&extra=page%3D1 这个歌词的时间设置还没有做过,还要改变一下? 小辣椒 发表于 2022-2-16 22:45
这个歌词的时间设置还没有做过,还要改变一下?
有空你仔细看看教程,看不懂没关系,关键是找到lrc歌词和如何构建 JS数组 黑黑你真的太厉害了,居然歌词同步都出来了,太佩服了{:4_199:} 小辣椒 发表于 2022-2-16 22:47
黑黑你真的太厉害了,居然歌词同步都出来了,太佩服了
这个不是太难,你看代码都不是很多 马黑黑 发表于 2022-2-16 22:47
有空你仔细看看教程,看不懂没关系,关键是找到lrc歌词和如何构建 JS数组
好的,看见你写着是手动的,我就把歌词直接修改一下可以吗
页:
[1]
2