前言
在之前我就想试试在线的音乐播放器的制作,昨晚动手实现了播放音乐的歌词实时对应显示的组件,下面就来看看其中的解析原理。
正文
这里我以李玉刚的《刚好遇见你》为例,首先我们需要获取到音频文件以及歌词的lrc内容,lrc歌词文件内容如下:
"[00:00.00] 作曲 : 高进\n[00:01.00] 作词 : 高进\n[00:12.56]我们哭了\n[00:15.27]我们笑着\n[00:18.60]我们抬头望天空\n[00:21.43]星星还亮着几颗\n[00:24.63]我们唱着\n[00:27.56]时间的歌\n[00:30.62]才懂得相互拥抱\n[00:34.00]到底是为了什么\n[00:36.94]因为我刚好遇见你\n[00:40.32]留下足迹才美丽\n[00:43.69]风吹花落泪如雨\n[00:46.48]因为不想分离\n[00:49.57]因为刚好遇见你\n[00:52.59]留下十年的期许\n[00:55.69]如果再相遇\n[00:59.15]我想我会记得你\n[01:14.28]我们哭了\n[01:16.88]我们笑着\n[01:20.29]我们抬头望天空\n[01:22.96]星星还亮着几颗\n[01:26.11]我们唱着\n[01:29.11]时间的歌\n[01:32.56]才懂得相互拥抱\n[01:35.36]到底是为了什么\n[01:38.47]因为我刚好遇见你\n[01:41.84]留下足迹才美丽\n[01:44.83]风吹花落泪如雨\n[01:47.97]因为不想分离\n[01:51.02]因为刚好遇见你\n[01:54.09]留下十年的期许\n[01:57.23]如果再相遇\n[02:00.69]我想我会记得你\n[02:03.69]因为刚好遇见你\n[02:06.43]留下足迹才美丽\n[02:09.57]风吹花落泪如雨\n[02:12.64]因为不想分离\n[02:15.76]因为刚好遇见你\n[02:18.78]留下十年的期许\n[02:21.83]如果再相遇\n[02:24.98]我想我会记得你\n[02:31.07]因为我刚好遇见你\n[02:34.13]留下足迹才美丽\n[02:37.25]风吹花落泪如雨\n[02:40.37]因为不想分离\n[02:43.43]因为刚好遇见你\n[02:46.48]留下十年的期许\n[02:49.58]如果再相遇\n[02:52.67]我想我会记得你\n"
现在对其歌词进行解析,歌词的解析写法参考了js解析lrc歌词-制作滚动歌词,如下:
var lyrics = this.lrc.split("\n");//this.lrc代表歌词文件内容的引用
var lrcObj = {};
for(var i=0;i<lyrics.length;i++){
var lyric = decodeURIComponent(lyrics[i]);
var timeReg = /\[\d*:\d*((\.|\:)\d*)*\]/g;
var timeRegExpArr = lyric.match(timeReg);
if(!timeRegExpArr)continue;
var clause = lyric.replace(timeReg,'');
for(var k = 0,h = timeRegExpArr.length;k < h;k++) {
var t = timeRegExpArr[k];
var min = Number(String(t.match(/\[\d*/i)).slice(1)),
sec = Number(String(t.match(/\:\d*/i)).slice(1));
var time = min * 60 + sec;
lrcObj[time] = clause;
}
}
return lrcObj;
上述代码会将你的歌词文件转换为数组,并且每个数组下标即为歌词的播放时间(单位:秒),接着在页面中添加一个音频组件,并引入音频文件:
<audio id="player" src="../assets/ghyjn.mp3" autoplay>
您的浏览器不支持 audio 标签。
</audio>
使用JS监听播放动态,并对每次的时间进行转换以此来对应数组下标然后更改页面上对应的歌词内容:
this.p.addEventListener("timeupdate",function(){
let obj = _this.lrcObj[Math.floor(this.currentTime)];
if(obj!=undefined){
_this.g = obj;
}
});
因为我是使用Vue+Webpack写的,所以页面中的完整代码如下:
<template>
<div class="hello" :style="'height:'+height+';width:100%'">
<audio id="player" src="../assets/ghyjn.mp3" autoplay>
您的浏览器不支持 audio 标签。
</audio>
<br>
<div class="c">
<div class="tc font30 mb15">{{g}}</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
g:'',
gd:{
up:null,
down:null
},
p:null,
lrc:"[00:00.00] 作曲 : 高进\n[00:01.00] 作词 : 高进\n[00:12.56]我们哭了\n[00:15.27]我们笑着\n[00:18.60]我们抬头望天空\n[00:21.43]星星还亮着几颗\n[00:24.63]我们唱着\n[00:27.56]时间的歌\n[00:30.62]才懂得相互拥抱\n[00:34.00]到底是为了什么\n[00:36.94]因为我刚好遇见你\n[00:40.32]留下足迹才美丽\n[00:43.69]风吹花落泪如雨\n[00:46.48]因为不想分离\n[00:49.57]因为刚好遇见你\n[00:52.59]留下十年的期许\n[00:55.69]如果再相遇\n[00:59.15]我想我会记得你\n[01:14.28]我们哭了\n[01:16.88]我们笑着\n[01:20.29]我们抬头望天空\n[01:22.96]星星还亮着几颗\n[01:26.11]我们唱着\n[01:29.11]时间的歌\n[01:32.56]才懂得相互拥抱\n[01:35.36]到底是为了什么\n[01:38.47]因为我刚好遇见你\n[01:41.84]留下足迹才美丽\n[01:44.83]风吹花落泪如雨\n[01:47.97]因为不想分离\n[01:51.02]因为刚好遇见你\n[01:54.09]留下十年的期许\n[01:57.23]如果再相遇\n[02:00.69]我想我会记得你\n[02:03.69]因为刚好遇见你\n[02:06.43]留下足迹才美丽\n[02:09.57]风吹花落泪如雨\n[02:12.64]因为不想分离\n[02:15.76]因为刚好遇见你\n[02:18.78]留下十年的期许\n[02:21.83]如果再相遇\n[02:24.98]我想我会记得你\n[02:31.07]因为我刚好遇见你\n[02:34.13]留下足迹才美丽\n[02:37.25]风吹花落泪如雨\n[02:40.37]因为不想分离\n[02:43.43]因为刚好遇见你\n[02:46.48]留下十年的期许\n[02:49.58]如果再相遇\n[02:52.67]我想我会记得你\n",
lrcObj:null,
height:'auto'
}
},
mounted(){
this.p = document.querySelector("#player")
let _this = this;
this.lrcObj = this.jx();
console.log(this.lrcObj);
this.p.addEventListener("timeupdate",function(){
let obj = _this.lrcObj[Math.floor(this.currentTime)];
if(obj!=undefined){
_this.g = obj;
}
});
this.height =window.innerHeight+'px'
window.onresize = ()=>{
_this.height =window.innerHeight+'px'
}
},
methods:{
jx(){
var lyrics = this.lrc.split("\n");
var lrcObj = {};
for(var i=0;i<lyrics.length;i++){
var lyric = decodeURIComponent(lyrics[i]);
var timeReg = /\[\d*:\d*((\.|\:)\d*)*\]/g;
var timeRegExpArr = lyric.match(timeReg);
if(!timeRegExpArr)continue;
var clause = lyric.replace(timeReg,'');
for(var k = 0,h = timeRegExpArr.length;k < h;k++) {
var t = timeRegExpArr[k];
var min = Number(String(t.match(/\[\d*/i)).slice(1)),
sec = Number(String(t.match(/\:\d*/i)).slice(1));
var time = min * 60 + sec;
lrcObj[time] = clause;
}
}
return lrcObj;
}
}
}
</script>
<style>
.hello{
background-image: url("../assets/by.jpg")
}
.c{
color: #927712;
}
.tc{
text-align: center;
margin:0 auto;
}
.mb15{
margin-bottom: 15px;
}
.font40{
font-size: 4rem;
}
.font30{
font-size: 3rem;
}
</style>