简单的HTML5音乐播放器(带歌词滚动)
2016-01-10 16:47
751 查看
// [00:00.08]光辉岁月
[00:00.82]演唱:Beyond
[00:01.51]
[00:29.09]钟声响起归家的讯号
[00:33.65]在他生命里
[00:36.87]彷佛带点唏嘘
[00:42.10]黑色肌肤给他的意义
[00:46.58]是一生奉献 肤色斗争中
[00:55.13]年月把拥有变做失去
[01:01.56]疲倦的双眼带著期望
[01:07.96]今天只有残留的躯壳
[01:11.68]迎接光辉岁月
[01:14.98]风雨中抱紧自由
[01:21.01]一生经过彷徨的挣扎
[01:24.65]自信可改变未来
[01:27.84]问谁又能做到
[01:31.49]
[01:43.73]可否不分肤色的界线
[01:48.27]愿这土地里
[01:51.69]不分你我高低
[01:56.69]缤纷色彩显出的美丽
[02:01.18]是因它没有
[02:04.39]分开每种色彩
[02:09.68]年月把拥有变做失去
[02:16.18]疲倦的双眼带著期望
[02:22.59]今天只有残留的躯壳
[02:26.25]迎接光辉岁月
[02:29.48]风雨中抱紧自由
[02:35.63]一生经过彷徨的挣扎
[02:39.26]自信可改变未来
[02:42.46]问谁又能做到
[02:46.00]
[03:24.19]今天只有残留的躯壳
[03:27.78]迎接光辉岁月
[03:31.07]风雨中抱紧自由
[03:37.15]一生经过彷徨的挣扎
[03:40.79]自信可改变未来
[03:44.04]问谁又能做到
[03:47.54]
[03:59.90]今天只有残留的躯壳
[04:03.52]迎接光辉岁月
[04:06.72]风雨中抱紧自由
[04:12.77]一生经过彷徨的挣扎
[04:16.45]自信可改变未来
[04:19.65]问谁又能做到
[04:23.04]
[04:35.56]今天只有残留的躯壳
[04:39.13]迎接光辉岁月
[04:42.37]风雨中抱紧自由
[04:48.50]一生经过彷徨的挣扎
[04:52.12]自信可改变未来
[04:54.85]
// ]]>
// var musicPlayer = function() {
return this.init.apply(this, arguments);
};
musicPlayer.prototype = {
constructor: musicPlayer,
init:function(options) {
if(isEmptyObj(options) || typeof options !== 'object') return;
this.player = options.player;
this.lrc = options.lrc;
this.lrcArea = options.lrcArea;
//用于保存歌词
this.lrcArr = [];
//用于保存时间戳
this.timestamp = [];
//处理歌词
this.handleLrc(this.lrc);
var that = this;
this.player.addEventListener('play', function() {
that.play();
}, false);
this.player.addEventListener('pause',function() {
that.pause();
}, false);
//歌词索引
this.idx = 0;
},
//格式化歌词
handleLrc:function(lrc) {
var re = /(\[.+\])(.+)?/gm,
ul = cEl('ul'),
frag = document.createDocumentFragment(),
tmpArr,i,len;
this.lrcArea.innerHTML = '';
frag.appendChild(ul);
ul.id = 'c';
this.lrcArea.appendChild(frag);
var txt = lrc.replace(re,function(a,b,c) {
return b + (c === undefined ? ' ' : c) + '\n';
});
tmpArr = txt.split('\n');
//处理歌词
for(i = 0,len = tmpArr.length; i < len; i++) {
var item = trim(tmpArr[i]);
if(item.length > 0) {
this.lrcArr.push(item);
}
}
frag = document.createDocumentFragment();
for(i = 0,len = this.lrcArr.length; i < len; i++) {
var li = cEl('li');
if(i === 0) {
li.className = 'cur';
}
li.innerHTML = this.lrcArr[i].replace(/\[.+\]/i,'')
.replace('// ]]>','').replace('//','');
//处理时间
this.timestamp.push(this.lrcArr[i].replace(re,function(a,b,c) {
return b;
}).replace('[','').replace(']',''));
frag.appendChild(li);
}
ul.appendChild(frag);
this.li = g('lrcArea').getElementsByTagName('li');
},
//播放
play:function() {
this.stop = false;
var that = this,
player = this.player,
i,len;
this.t = setInterval(function() {
if(that.stop) return;
that.curTime = player.currentTime;
for(i = 0,len = that.timestamp.length - 1; i < len; i++) {
var prevTime = that.formatTimeStamp( that.timestamp[i] ),
nextTime = that.formatTimeStamp( that.timestamp[i + 1] );
//当前播放时间与前后歌词时间比较,如果位于这两者之间则转到该歌词
if( parseFloat( that.curTime ) > prevTime && parseFloat( that.curTime ) < nextTime ) {
that.scrollToLrc(i);
return;
}
}
},300);
},
//暂停
pause:function() {
this.stop = true;
clearInterval(this.t);
},
//格式化时间
formatTimeStamp:function(timestamp) {
var re = /([0-9]+):([0-9]+)\.([0-9]+)/i,
seconds = timestamp.replace(re,function(a,b,c,d) {
return Number(b * 60) + Number(c) + parseFloat('0.'+ d);
});
return seconds;
},
//歌词滚动
scrollToLrc:function(idx) {
var ds = getOffset(this.li[idx]).top,
i,len;
//如果歌词索引没有变动,则认为这句没有唱完,不处理
if(this.idx === idx) return;
//否则更新索引值并更新样式和位置
this.idx = idx;
for(i = 0,len = this.li.length; i < len; i++) {
this.li[i].className = '';
}
this.li[idx].className = 'cur';
this.lrcArea.scrollTop = ds - this.lrcArea.offsetHeight / 2;
}
};
function g(id) {
return typeof id === 'string' ? document.getElementById(id) : id;
}
function cEl(el) {
return document.createElement(el);
}
function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
}
function isEmptyObj(o) {
for(var p in o) return false;
return true;
}
function getOffset(el) {
var parent = el.offsetParent,
left = el.offsetLeft,
top = el.offsetTop;
while(parent !== null) {
left += parent.offsetLeft;
top += parent.offsetTop;
parent = parent.offsetParent;
}
return {
left: left,
top: top
};
}
var p = new musicPlayer({
player: g('player'),
lrc: g('lrc').innerHTML,
lrcArea: g('lrcArea')
});
// ]]>
首先需要整理好lrc格式的歌词放到script标签中以供程序处理。然后把音乐链接放到audio的src属性里就可以了。
源码:
HTML部分
JS部分
View Code
[00:00.82]演唱:Beyond
[00:01.51]
[00:29.09]钟声响起归家的讯号
[00:33.65]在他生命里
[00:36.87]彷佛带点唏嘘
[00:42.10]黑色肌肤给他的意义
[00:46.58]是一生奉献 肤色斗争中
[00:55.13]年月把拥有变做失去
[01:01.56]疲倦的双眼带著期望
[01:07.96]今天只有残留的躯壳
[01:11.68]迎接光辉岁月
[01:14.98]风雨中抱紧自由
[01:21.01]一生经过彷徨的挣扎
[01:24.65]自信可改变未来
[01:27.84]问谁又能做到
[01:31.49]
[01:43.73]可否不分肤色的界线
[01:48.27]愿这土地里
[01:51.69]不分你我高低
[01:56.69]缤纷色彩显出的美丽
[02:01.18]是因它没有
[02:04.39]分开每种色彩
[02:09.68]年月把拥有变做失去
[02:16.18]疲倦的双眼带著期望
[02:22.59]今天只有残留的躯壳
[02:26.25]迎接光辉岁月
[02:29.48]风雨中抱紧自由
[02:35.63]一生经过彷徨的挣扎
[02:39.26]自信可改变未来
[02:42.46]问谁又能做到
[02:46.00]
[03:24.19]今天只有残留的躯壳
[03:27.78]迎接光辉岁月
[03:31.07]风雨中抱紧自由
[03:37.15]一生经过彷徨的挣扎
[03:40.79]自信可改变未来
[03:44.04]问谁又能做到
[03:47.54]
[03:59.90]今天只有残留的躯壳
[04:03.52]迎接光辉岁月
[04:06.72]风雨中抱紧自由
[04:12.77]一生经过彷徨的挣扎
[04:16.45]自信可改变未来
[04:19.65]问谁又能做到
[04:23.04]
[04:35.56]今天只有残留的躯壳
[04:39.13]迎接光辉岁月
[04:42.37]风雨中抱紧自由
[04:48.50]一生经过彷徨的挣扎
[04:52.12]自信可改变未来
[04:54.85]
// ]]>
// var musicPlayer = function() {
return this.init.apply(this, arguments);
};
musicPlayer.prototype = {
constructor: musicPlayer,
init:function(options) {
if(isEmptyObj(options) || typeof options !== 'object') return;
this.player = options.player;
this.lrc = options.lrc;
this.lrcArea = options.lrcArea;
//用于保存歌词
this.lrcArr = [];
//用于保存时间戳
this.timestamp = [];
//处理歌词
this.handleLrc(this.lrc);
var that = this;
this.player.addEventListener('play', function() {
that.play();
}, false);
this.player.addEventListener('pause',function() {
that.pause();
}, false);
//歌词索引
this.idx = 0;
},
//格式化歌词
handleLrc:function(lrc) {
var re = /(\[.+\])(.+)?/gm,
ul = cEl('ul'),
frag = document.createDocumentFragment(),
tmpArr,i,len;
this.lrcArea.innerHTML = '';
frag.appendChild(ul);
ul.id = 'c';
this.lrcArea.appendChild(frag);
var txt = lrc.replace(re,function(a,b,c) {
return b + (c === undefined ? ' ' : c) + '\n';
});
tmpArr = txt.split('\n');
//处理歌词
for(i = 0,len = tmpArr.length; i < len; i++) {
var item = trim(tmpArr[i]);
if(item.length > 0) {
this.lrcArr.push(item);
}
}
frag = document.createDocumentFragment();
for(i = 0,len = this.lrcArr.length; i < len; i++) {
var li = cEl('li');
if(i === 0) {
li.className = 'cur';
}
li.innerHTML = this.lrcArr[i].replace(/\[.+\]/i,'')
.replace('// ]]>','').replace('//','');
//处理时间
this.timestamp.push(this.lrcArr[i].replace(re,function(a,b,c) {
return b;
}).replace('[','').replace(']',''));
frag.appendChild(li);
}
ul.appendChild(frag);
this.li = g('lrcArea').getElementsByTagName('li');
},
//播放
play:function() {
this.stop = false;
var that = this,
player = this.player,
i,len;
this.t = setInterval(function() {
if(that.stop) return;
that.curTime = player.currentTime;
for(i = 0,len = that.timestamp.length - 1; i < len; i++) {
var prevTime = that.formatTimeStamp( that.timestamp[i] ),
nextTime = that.formatTimeStamp( that.timestamp[i + 1] );
//当前播放时间与前后歌词时间比较,如果位于这两者之间则转到该歌词
if( parseFloat( that.curTime ) > prevTime && parseFloat( that.curTime ) < nextTime ) {
that.scrollToLrc(i);
return;
}
}
},300);
},
//暂停
pause:function() {
this.stop = true;
clearInterval(this.t);
},
//格式化时间
formatTimeStamp:function(timestamp) {
var re = /([0-9]+):([0-9]+)\.([0-9]+)/i,
seconds = timestamp.replace(re,function(a,b,c,d) {
return Number(b * 60) + Number(c) + parseFloat('0.'+ d);
});
return seconds;
},
//歌词滚动
scrollToLrc:function(idx) {
var ds = getOffset(this.li[idx]).top,
i,len;
//如果歌词索引没有变动,则认为这句没有唱完,不处理
if(this.idx === idx) return;
//否则更新索引值并更新样式和位置
this.idx = idx;
for(i = 0,len = this.li.length; i < len; i++) {
this.li[i].className = '';
}
this.li[idx].className = 'cur';
this.lrcArea.scrollTop = ds - this.lrcArea.offsetHeight / 2;
}
};
function g(id) {
return typeof id === 'string' ? document.getElementById(id) : id;
}
function cEl(el) {
return document.createElement(el);
}
function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
}
function isEmptyObj(o) {
for(var p in o) return false;
return true;
}
function getOffset(el) {
var parent = el.offsetParent,
left = el.offsetLeft,
top = el.offsetTop;
while(parent !== null) {
left += parent.offsetLeft;
top += parent.offsetTop;
parent = parent.offsetParent;
}
return {
left: left,
top: top
};
}
var p = new musicPlayer({
player: g('player'),
lrc: g('lrc').innerHTML,
lrcArea: g('lrcArea')
});
// ]]>
首先需要整理好lrc格式的歌词放到script标签中以供程序处理。然后把音乐链接放到audio的src属性里就可以了。
源码:
HTML部分
<div class="container"> <audio id="player" src="test.mp3" loop controls preload></audio> <div id="lrcArea"></div> </div> <script id="lrc" type="text"> //lrc歌词 </script>
JS部分
var musicPlayer = function() { return this.init.apply(this, arguments); }; musicPlayer.prototype = { constructor: musicPlayer, init: function(options) { if (isEmptyObj(options) || typeof options !== 'object') return; this.player = options.player; this.lrc = options.lrc; this.lrcArea = options.lrcArea; //用于保存歌词 this.lrcArr = []; //用于保存时间戳 this.timestamp = []; //处理歌词 this.handleLrc(this.lrc); var that = this; this.player.addEventListener('play', function() { that.play(); }, false); this.player.addEventListener('pause', function() { that.pause(); }, false); //歌词索引 this.idx = 0; }, //格式化歌词 handleLrc: function(lrc) { var re = /(\[.+\])(.+)?/gm, ul = cEl('ul'), frag = document.createDocumentFragment(), tmpArr, i, len; this.lrcArea.innerHTML = ''; frag.appendChild(ul); ul.id = 'c'; this.lrcArea.appendChild(frag); var txt = lrc.replace(re, function(a, b, c) { return b + (c === undefined ? ' ': c) + '\n'; }); tmpArr = txt.split('\n'); //处理歌词 for (i = 0, len = tmpArr.length; i < len; i++) { var item = trim(tmpArr[i]); if (item.length > 0) { this.lrcArr.push(item); } } frag = document.createDocumentFragment(); for (i = 0, len = this.lrcArr.length; i < len; i++) { var li = cEl('li'); if (i === 0) { li.className = 'cur'; } li.innerHTML = this.lrcArr[i].replace(/\[.+\]/i, ''); //处理时间 this.timestamp.push(this.lrcArr[i].replace(re, function(a, b, c) { return b; }).replace('[', '').replace(']', '')); frag.appendChild(li); } ul.appendChild(frag); this.li = $('lrcArea').getElementsByTagName('li'); }, //播放 play: function() { this.stop = false; var that = this, player = this.player, i, len; this.t = setInterval(function() { if (that.stop) return; that.curTime = player.currentTime; for (i = 0, len = that.timestamp.length - 1; i < len; i++) { var prevTime = that.formatTimeStamp(that.timestamp[i]), nextTime = that.formatTimeStamp(that.timestamp[i + 1]); //当前播放时间与前后歌词时间比较,如果位于这两者之间则转到该歌词 if (parseFloat(that.curTime) > prevTime && parseFloat(that.curTime) < nextTime) { that.scrollToLrc(i); return; } } }, 300); }, //暂停 pause: function() { this.stop = true; clearInterval(this.t); }, //格式化时间 formatTimeStamp: function(timestamp) { var re = /([0-9]+):([0-9]+)\.([0-9]+)/i, seconds = timestamp.replace(re, function(a, b, c, d) { return Number(b * 60) + Number(c) + parseFloat('0.' + d); }); return seconds; }, //歌词滚动 scrollToLrc: function(idx) { var ds = getOffset(this.li[idx]).top, i, len; //如果歌词索引没有变动,则认为这句没有唱完,不处理 if (this.idx === idx) return; //否则更新索引值并更新样式和位置 this.idx = idx; for (i = 0, len = this.li.length; i < len; i++) { this.li[i].className = ''; } this.li[idx].className = 'cur'; this.lrcArea.scrollTop = ds - this.lrcArea.offsetHeight / 2; } }; function $(id) { return typeof id === 'string' ? document.getElementById(id) : id; } function cEl(el) { return document.createElement(el); } function trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } function isEmptyObj(o) { for (var p in o) return false; return true; } function getOffset(el) { var parent = el.offsetParent, left = el.offsetLeft, top = el.offsetTop; while (parent !== null) { left += parent.offsetLeft; top += parent.offsetTop; parent = parent.offsetParent; } return { left: left, top: top }; } var p = new musicPlayer({ player: $('player'), lrc: $('lrc').innerHTML, lrcArea: $('lrcArea') });
View Code
相关文章推荐
- HTML5 Canvas绘图详解 drawImage() 方法 有图有真相!
- 实际项目&其他
- html5表单新特性
- 【html5】html5 本地存储
- HTML5调用摄像头实现拍照功能(兼容各大主流浏览器)
- 15个最好的HTML5前端响应式框架(2014)
- HTML5:组织文档结构
- 下拉菜单得经典写法html5
- HTML5 <label> 标签
- HTML5表单及其验证
- html5视频播放器
- html5新增元素
- 学习H5不错的书籍
- html5新增的type类型
- HTML5的LocalStorage、SessionStorage学习
- Iphone H5上传照片被旋转
- Iphone H5上传照片被旋转
- Iphone H5上传照片被旋转
- Html5-测试Canvas
- 图解用HTML5的popstate如何玩转浏览器历史记录