LRC歌词是什么?
LRC歌词是英文lyric(歌词)的缩写,基于纯文本的歌词专用格式,被用做歌词文件的扩展名。其实还有很多其他的歌词格式,比如酷狗音乐的krc,QQ音乐的qrc之类的。大部分的音乐站都还是使用的LRC。
LRC歌词内容类型标签
一个完整的LRC歌词文件,一般包含标识标签和时间标签。
LRC歌词编写相对比较自由,只要大体上的时间线是对的,基本就可以用。
[00:05.16]有的也写成[0:5.16]这样的格式
有的歌词里面甚至一行有2个甚至3个时间,这都是非常场常见。
新建一个html文件
在文件中创建一个div用于装歌词
<style>
.fzyplayer-lrc{
align-items: center;
justify-content: center;
text-align: center;
height: 255px;
max-height: 255px;
width: 100%;
position: relative;
}
.fzyplayer-lyric-area{
width: 100%;
position: absolute;
text-align: center;
justify-content: center;
align-items: center;
height: 255px;
min-height: 255px;
max-height: 255px;
overflow: hidden;
top: 0;
-webkit-mask-image: linear-gradient(
to bottom,
rgba(255, 255, 255, 0) 0,
rgba(255, 255, 255, 0.6) 15%,
rgba(255, 255, 255, 1) 25%,
rgba(255, 255, 255, 1) 75%,
rgba(255, 255, 255, 0.6) 85%,
rgba(255, 255, 255, 0) 100%
);
}
.fzyplayer-lyric{
padding: 0!important;
width: 100%;
height:100%;
position: absolute;
transition: top 1s linear;
}
.fzyplayer-lyric>li{
width: 100%;
/*color: rgba(0,0,0,.6);*/
font-weight: 500;
line-height: 35px;
font-size: 16px;
text-align: center;
user-select:none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
transition: all 0.3s;
text-shadow: 1px 1px rgba(0, 0, 0, 0.2),
1px 2px rgba(0, 0, 0, 0.1);
display: table!important;
}
.fzyplayer-lyric>.active{
font-size: 18px;
color: #fff;
font-weight: 800;
/*color: #c62f2f;*/
background-image: linear-gradient(
to right,
#c62f2f,
orange,
yellow,
green,
yellow,
orange,
red,
orange,
yellow,
green,
yellow,
orange,
#c62f2f
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 200% 100%;
animation: bgp 5s infinite linear;
}
@keyframes bgp {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}
</style>
<div class="fzyplayer-lrc">
<div class="fzyplayer-lyric-area">
<ul class="fzyplayer-lyric">
<li class="active">欢迎使用风之涯播放器,精彩由你而写</li>
</ul>
</div>
</div>
JS部分
if(typeof binlyric != 'object') { binlyric = {};}
binlyric = {
edition:"1.1",
obj:"",
lyricCSS:new Object(),
txt:"",
index:0,
time:new Array(),
lyric:new Array(),
sort:function(){ // 冒泡排序(从小到大)
var third;
for(var j=0;j<this.index-1;j++)
{
for(var i=0;i<this.index-1;i++)
{
if(this.time[i]>this.time[i+1])
{
third = this.time[i];
this.time[i] = this.time[i+1];
this.time[i+1] = third;
third = this.lyric[i];
this.lyric[i] = this.lyric[i+1];
this.lyric[i+1] = third;
}
}
}
},
createPanel:function(){ // 创建歌词面板
var i=0;
$(this.obj).html("").css({'top':'95px'});
for(i=0;i<this.index;i++)
{
$(this.obj).append("<li>"+this.lyric[i]+"</li>");
}
},
findTags:function(index,strArray,number){ // 查找标签(包括任何扩展的标签)
// 此方法能匹配所有格式的标签
// 因为此方法是在后面写的,所以时间标签并没有使用此方法
number = number || this.txt.length;
number = (number>this.txt.length) ? this.txt.length:number;
var i,j,complete=0,value;
var obj = new Object();
obj.booble = false;
obj.value = "[";
for(i=index;i<number;i++)
{
if(this.txt.substr(i,1)==strArray[complete].s)
{
complete+=1;
if(complete>1)
{
if(complete<strArray.length)
{
obj.value += '{value:"'+this.txt.substr(value+1,i-value-1)+'"},';
}
else
{
obj.value += '{value:"'+this.txt.substr(value+1,i-value-1)+'"}]';
}
}
if(complete==strArray.length)
{
obj.txt = this.txt.substr(index,i-index+1);
obj.value = eval('('+obj.value+')');
obj.index = i+1;
obj.booble = true;
break
}
value = i;
}
else if(this.txt.substr(i,1)=="\n")
{
obj.booble = false;
return obj;
}
else if(this.txt.substr(i,1)==strArray[0].s && complete>0) // 遇到2次开始标志就退出
{
obj.booble = false;
return obj;
}
}
return obj;
},
findlyric:function(index){ // 查找歌词: 有则返回 歌词、继续查找的位置, 否则只返回继续查找的位置
var obj = {};
var str = this.txt;
var i;
for(i=index;i<str.length;i++)
{
if(str.charAt(i)=="[")
{
var _obj = this.findTags(i,[{s:"["},{s:":"},{s:"]"}]);
if(_obj.booble)
{
obj.index = i;//i + _obj.txt.length;
obj.lyric = str.substr(index,i-index);
return obj;
}
}
else if(str.charAt(i)=="\n")
{
obj.index = i+1;
obj.lyric = str.substr(index,i-index);
return obj
}
}
if(i==str.length) // 专处理最后一句歌词(最后一句歌词比较特殊)
{
obj.index = i+1;
obj.lyric = str.substr(index,i-index);
return obj;
}
obj.index = i;
return obj;
},
findTime:function(index){ // 查找时间 : 有则返回 时间、继续查找的位置, 否则只返回继续查找的位置
// 此功能可以用 findTags 方法实现,更简单、更强大、代码更少
// findTags方法 是在后面写的,所以这里就不改了,具体可参考 findID方法里的使用实例
var obj = {};
var thisobj = this;
var str = this.txt;
obj.index = index;
function recursion()
{
var _obj = thisobj.findTime(obj.index);
if(_obj.time)
{
obj.time += _obj.time;
obj.index = _obj.index;
}
}
// --------------- 可以在这里 扩展 其它功能 ---------------
// lrc歌词只能精确到每句歌词,可以通过扩展lrc 精确 到 每个字
if(/\[\d{1,2}\:\d{1,2}\.\d{1,2}\]/.test(str.substr(index,10))) // [mm:ss.ff]
{
obj.time = str.substr(index+1,8) + "|";
obj.index = index+9+1;
recursion();
}
else if(/\[\d{1,2}\:\d{1,2}\.\d{3}\]/.test(str.substr(index,11))) //[mm:ss.fff]
{
obj.time = str.substr(index+1,9) + "|";
obj.index = index+10+1;
recursion();
}
else if(/\[\d{1,2}\:\d{1,2}\]/.test(str.substr(index,7))) // [mm:ss]
{
obj.time = str.substr(index+1,5) + ".00" + "|";
obj.index = index+6+1;
recursion();
}
// 以下标签均属于合法标签,但很少被使用,请根据需要进行扩展
// [mm:ss.f] [mm:s.ff] [mm:s.f] [m:ss.ff] [m:s.ff] [m:s.f]
// [mm:s] [m:ss] [s:s]
return obj;
},
findID:function(index){ // 查找预定义标识
//[ar:艺人名]
//[ti:曲名]
//[al:专辑名]
//[by:编者(指编辑LRC歌词的人)]
//[offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢的。(很少被使用)
// 注:本程序也不支持 offset 功能(但是能取值),如需要 请自行在 sort 方法添加此功能
// 此处功能 使用 findTags方法 实现
var obj;
obj = this.findTags(index,[{s:"["},{s:":"},{s:"]"}]);
if(obj.booble)
{
if(obj.value[0].value=="ar")
{
this.ar = obj.value[1].value;
}
else if(obj.value[0].value=="ti")
{
this.ti = obj.value[1].value;
}
else if(obj.value[0].value=="al")
{
this.al = obj.value[1].value;
}
else if(obj.value[0].value=="by")
{
this.by = obj.value[1].value;
}
else if(obj.value[0].value=="offset") // 这里是 offset 的值
{
this.offset = obj.value[1].value;
}
}
},
analysis:function(){ // 解析
if(this.txt=="") return false;
var str = this.txt;
this.index = 0;
for(var i=0;i<str.length;i++)
{
if(str.charAt(i)=="[")
{
var time = this.findTime(i);
if(time.time) // 时间标签
{
var lyric = this.findlyric(time.index);
if(lyric.lyric!="\n" && lyric.lyric!="") // 去掉无意义歌词
{
var timeArray = time.time.split("|");
for(var j=0;j<timeArray.length;j++)
{
if(timeArray[j])
{
this.time[this.index] = timeArray[j];
this.lyric[this.index] = lyric.lyric;
this.index+=1;
}
}
}
i = time.index;
}
else // 预定义标签
{
this.findID(i);
}
}
}
if(this.time.length<1){ //歌词出错
this.time = ['00:01.000'];
this.lyric = ['没有歌词展示'];
this.index = 1;
}
this.sort();
this.createPanel();
},
play:function(position,CSS){ // 定位指定时间的歌词
var time;
var obj = this;
function set(index)
{
let num = (-35*index+95)+'px';
$(obj.obj).css("top",num);
$(obj.obj).find('li').eq(index).addClass('active').siblings().removeClass('active');
}
for(var i=0;i<this.index;i++)
{
if(position==this.time[i])
{
let set = new Set();
set.add(i);
return;
}
else if(position>this.time[i])
{
time = i;
}
}
set(time);// 没找到匹配时间 则就近最小选择
}
};
相对都比较简单
调用JS
//装入歌词
binlyric.txt = '完整歌词内容';
binlyric.obj = '.fzyplayer-lyric';
binlyric.analysis();//执行方法
//播放歌词 此段写入播放器timeupdate事件内
//例如播放器
let player=document.getElementById('audio');
player.addEventListener('timeupdate',function(){
let curTime = player.currentTime;
//转换为00:00.102格式
let mm = parseInt(curTime/60);
mm = mm<10?('0'+mm):mm;
let ff =(curTime%60).toFixed(2);
ff = ff<10 ? ('0'+ff) :ff;
binlyric.play(mm+':'+ff); //执行歌词就靠这一句
});
演示
- 欢迎使用风之涯播放器,精彩由你而写
评论 (0)