-
Notifications
You must be signed in to change notification settings - Fork 8
/
audio.js
178 lines (164 loc) · 5.54 KB
/
audio.js
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/**
* WebAudio.js
* HTML5的音频播放组件,兼容解决iOS系统下自动播放(autoplay)和循环播放(loop)的问题
* https://github.com/tjuking/audio.js
*/
(function (global, factory) {
"use strict";
if (typeof define === "function" && define.amd) {
define(function () {
return factory();
});
} else if (typeof exports !== "undefined") {
module.exports = factory();
} else {
global.WebAudio = factory();
}
})(window, function () {
"use strict";
/**
* 封装的audio操作对象
* @param option {object} 传入的参数
* @constructor
*/
var WebAudio = function (option) {
var events = [
"canplay", "canplaythrough", "durationchange", "emptied", "ended", "error",
"onloadeddata", "loadedmetadata", "loadstart", "pause", "play", "playing",
"progress", "ratechange", "readystatechange", "seeked", "seeking", "stalled",
"suspend", "timeupdate", "volumechange", "waiting"
];
var noop = function () { //空函数
};
var i;
var key;
option = option || {};
this._events = events;
this.options = {
src: "", //声音来源
autoPlay: false, //是否自动播放,默认是false
loop: false, //是否循环播放,默认是false
duration: 0 //声音长度,单位是秒
};
for (i = 0; i < events.length; i++) {
this.options["on" + firstLetterUppercase(events[i])] = noop; //例如:"onEnded"
}
for (key in option) {
if (option.hasOwnProperty(key)) {
this.options[key] = option[key];
}
}
this.audio = new Audio();
this._init();
};
WebAudio.prototype = {
constructor: WebAudio,
/**
* 初始化入口函数
* @private
*/
_init: function () {
var that = this;
var i;
var inIOS = isIOS();
var options = this.options;
for (i = 0; i < this._events.length; i++) { //添加事件
this._addEventListener(this._events[i]);
}
if (inIOS) { //在iOS中的处理比较特殊一些
if (options.loop) { //设置了循环播放
//通过时间更新来判断是否需要开始重新播放
this.audio.addEventListener("timeupdate", function (e) {
if (_getDuration() - that.audio.currentTime <= 0.8) { //当距离总时间小于0.2秒时,将重新播放
that.audio.currentTime = 0;
}
}, false);
}
if (options.autoPlay) { //设置了自动播放
document.addEventListener("touchstart", _autoPlay, false); //需要用户交互才能开始播放
}
} else { //非iOS环境下
if (options.loop) { //设置了循环播放
this.audio.loop = true;
}
if (options.autoPlay) { //设置了自动播放
_autoPlay();
}
}
/**
* iOS下自动播放开始,完成后需要移除事件绑定
* @private
*/
function _autoPlay() {
that.load();
that.play();
if (inIOS) {
document.removeEventListener("touchstart", _autoPlay, false);
}
}
/**
* 获取音频的时长
* @returns {number} 音频的时长
* @private
*/
function _getDuration() {
var duration = that.options.duration; //默认是用户传入的时间
var audioDuration = that.audio.duration; //实际的音频长度(优先级更高)
if (typeof audioDuration === "number" && !isNaN(audioDuration) && isFinite(audioDuration)) {
duration = audioDuration;
}
return duration;
}
},
/**
* 加载音频文件
* @param [src] {string} 音频文件的地址
*/
load: function (src) {
this.audio.src = src || this.options.src;
},
/**
* 播放
*/
play: function () {
this.audio.play();
},
/**
* 暂停
*/
pause: function () {
this.audio.pause();
},
/**
* 添加事件
* @param event {string} 事件名称
* @private
*/
_addEventListener: function (event) {
var that = this;
this.audio.addEventListener(event, function (e) {
that.options["on" + firstLetterUppercase(event)].call(that, e);
}, false);
}
};
/**
* 首字母大写
* @param word {string} 传入的字符串
* @returns {string} 首字母大写后的字符串
*/
function firstLetterUppercase(word) {
if (typeof word === "string" && word.length) { //是字符串且长度不为0
return word[0].toUpperCase() + word.substring(1);
} else {
return word;
}
}
/**
* 检测是否为iOS中
* @returns {boolean} 是否在iOS中
*/
function isIOS() {
return /iPad|iPhone|iPod/i.test(navigator.userAgent) && !window.MSStream;
}
return WebAudio;
});