音乐播放器插件

cloudmusic

Liric音乐网站

  • 一个主要素材为audio的网站

audio音乐播放器

最近收到任务要做一个音乐的官网,花了个寒假实现了出来,但总觉得不太满意。原因不过是最重要的部分–播放器的功能不够强大。
最近索性将这部分功能分离出来进行优化。诺,这便有了这篇文章。

这里是Zenaro的 Z-Player Javascript音乐插件! 这是笔者目前针对audio性能所改进的优化方案,
主要是针对HTML5的 audio 标签进行 DOM 和 UI 的优化。

卖个小广告就把自己做的整个网站都贴了出来,想看网站的客官请移步 这里

网站代码我也放在 Github 上面了,戳 [这里] (https://github.com/Zenaro/FE-CloudMusic)查看源代码

接下来呢,lz就只单独分析下播放器部分的代码了,播放器的样子如下图:

Z-Player

播放器的代码包我也已经单独分出来,放在 Github上面啦,直接git下来就可以体验得到效果啦。

插件 简介

插件的主要功能包括构建插件样式和DOM控制,并在最后公开播放方法。以实现调用插件即可使用的效果。而且插件的css为悬浮定位,不会影响到原页面的布局~
具体调用只需要 new 出插件实例就都搞定了

1
2
3
var Player = require('./player');
var p = new Player(json); // json为歌曲信息,下文会分析
Player.render(); // render为构建插件的方法

如何使用

项目稍微大一些的都需要JS模块化开发,这个插件为了走向大众化也使用了。作者这里用的是seajs,毕竟seajs可是来自大陆的阿里模块化js神器,怎么也得支持一下,这里我们新建一个空的html文件,然后引入player.css样式和seajs配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Player</title>
<link rel="stylesheet" href="./dest/css/player.css"/>
<style>
html, body { width: 100%; height: 100%; }
</style>
</head>
<body>

<script type="text/javascript" src="./sea-modules/seajs/sea.js"></script>
<script type="text/javascript">
seajs.config({ //设置configuration
base: "./sea-modules",
alias: {
"jquery" : "jquery/jquery.js"
}
});
seajs.use('./src/js/main'); // 引入main.js
</script>
</body>
</html>

接着便是main.js的写法了,假设你的项目里面已经有很多个模块了,这时候player作为新的模块被引入进来

1
2
3
4
5
6
7
8
9
10
11
define(function (require) {
// ...其他模块

// player模块
var json = require('./data');
var Player = require('./player');
var p = new Player(json);
p.render();

// ...更多模块
});

这里的data模块只是我自己写上去的一些歌曲测试数据而已,包括了若干歌曲的曲名,歌手,和路径。通过引入json数据来对player进行初始化。

最后是如何调用player,简单直接使用接口就行

1
p.init(data);		// 某首歌曲的数据,

到了这里,大家是不是已经开着插件在听歌了呢?那接下来要开始讲代码,不喜欢代码的童鞋千万不要往下看…

JS代码分析

插件框架一览
首先我们创建 Player 对象,它包含了以下几个属性和方法。最后别忘了暴露出这个Player模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
define(function (require, exports, module) {

function Player(json) {
this.global = null; // 祖先元素
this.audio = null; // audio对象
this.loopType = 2; // 1->单曲循环, 2->列表循环 3->随机播放 循环类型
this.json = json;
this.curTrack = null; // 当前歌曲的json数据
this.prvTrack = null; // 上一条曲目的json
this.nxtTrack = null; // 下一条曲目的json
}

module.exports = Player; // 暴露Player

Player.prototype.render = function() {
var $ = require('jquery'); // 引入jquery依赖
this._createEl(); // 创建 UI
this._bind(); // 启动事件监听器
};

Player.prototype.init = function (data) { //向外暴露的播放方法

}

Player.prototype._bind = function() { // 一些事件绑定

}

Player.prototype._createEl = function() { // 创建UI

}
});

JS具体实现

插件里面很多都是一看就懂的,这里篇幅有限,我就直接讲一些值得一提的地方吧

this.audio

比较有趣的第一点是this.audio的赋值。
我们一开始可能觉得它应该是$(‘audio’)标签,其实不然,这里的$(‘audio’)只是一个节点对象,html赋给audio的所有属性都是在这个节点的第0个索引上(即audio对象上)的。我们来控制台测试下$(‘audio’)是神马

1
2
3
4
5
6
7
8
9
console.log($('audio'));

[audio, prevObject: jQuery.fn.jQuery.init[1], context: document, selector: "audio"]
0: audio
context: document
length: 1
prevObject: jQuery.fn.jQuery.init[1]
selector: "audio"
__proto__: Object[0]

可以看到$(‘audio’)[0]才是我们想要的对象

html5媒体事件

第二点呢,应该是html5的audio事件了。
当初第一个版本的时候完全不知道有这么个东西,播放进度条啊时钟啊什么的全部用setInterval来做了,结果呢效果虽然做出来了,但是页面变得好卡好卡。
做音乐的页面都会很卡么?为此我特地跑去别人家的音乐官网上测试别人家的性能=.=,惊讶地发现别人的并不会卡呀。
看来是我的优化没做好,百度了一番也修改了一番,最后发现罪魁祸首是setInterval。原来html5封装了一些优秀的媒体事件供我们调用,既然是权威封装好了的性能自然不差,比我们自己随意使用setInterval去实现时钟要好多了。
到此果断换掉所有的setInterval,用上媒体事件~,结果就有了这个新版的player插件了
在这里分享几个很好用的audio事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(this.audio).on('canplay', function() {	// 当媒体缓冲得足以开始播放时要做什么 
// 可以隐藏loading.gif
}).on('play', function() { // 歌曲播放时要做什么

}).on('timeupdate', function() { // 时间变化时要做的事情,如驱动播放条慢慢向前

}).on('pause', function() { // 歌曲停止时要做什么

}).on('durationchange', function() { // 歌曲的总时间变化了要做什么

}).on('loadstart', function() { // 开始加载了但还没加载好
// 可以显示loading.gif
}).on('progress', function() { // 正在缓冲

}).on('volumechange', function() { // 音量变化了

}).on('ended', function() { // 歌曲播放结束了

});

辣,今天就先分享到这里,下次再慢慢补番,233333
相关资料 web audio api / audio对象

最近访客