rc-web@66
|
1 // ----------------------------------------------------------------------------
|
rc-web@66
|
2 // Buzz, a Javascript HTML5 Audio library
|
rc-web@66
|
3 // v 1.0.4 beta
|
rc-web@66
|
4 // Licensed under the MIT license.
|
rc-web@66
|
5 // http://buzz.jaysalvat.com/
|
rc-web@66
|
6 // ----------------------------------------------------------------------------
|
rc-web@66
|
7 // Copyright (C) 2011 Jay Salvat
|
rc-web@66
|
8 // http://jaysalvat.com/
|
rc-web@66
|
9 // ----------------------------------------------------------------------------
|
rc-web@66
|
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
rc-web@66
|
11 // of this software and associated documentation files ( the "Software" ), to deal
|
rc-web@66
|
12 // in the Software without restriction, including without limitation the rights
|
rc-web@66
|
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
rc-web@66
|
14 // copies of the Software, and to permit persons to whom the Software is
|
rc-web@66
|
15 // furnished to do so, subject to the following conditions:
|
rc-web@66
|
16 //
|
rc-web@66
|
17 // The above copyright notice and this permission notice shall be included in
|
rc-web@66
|
18 // all copies or substantial portions of the Software.
|
rc-web@66
|
19 //
|
rc-web@66
|
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
rc-web@66
|
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
rc-web@66
|
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
rc-web@66
|
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
rc-web@66
|
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
rc-web@66
|
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
rc-web@66
|
26 // THE SOFTWARE.
|
rc-web@66
|
27 // ----------------------------------------------------------------------------
|
rc-web@66
|
28
|
rc-web@66
|
29 var buzz = {
|
rc-web@66
|
30 defaults: {
|
rc-web@66
|
31 autoplay: false,
|
rc-web@66
|
32 duration: 5000,
|
rc-web@66
|
33 formats: [],
|
rc-web@66
|
34 loop: false,
|
rc-web@66
|
35 placeholder: '--',
|
rc-web@66
|
36 preload: 'metadata',
|
rc-web@66
|
37 volume: 80
|
rc-web@66
|
38 },
|
rc-web@66
|
39 types: {
|
rc-web@66
|
40 'mp3': 'audio/mpeg',
|
rc-web@66
|
41 'ogg': 'audio/ogg',
|
rc-web@66
|
42 'wav': 'audio/wav',
|
rc-web@66
|
43 'aac': 'audio/aac',
|
rc-web@66
|
44 'm4a': 'audio/x-m4a'
|
rc-web@66
|
45 },
|
rc-web@66
|
46 sounds: [],
|
rc-web@66
|
47 el: document.createElement( 'audio' ),
|
rc-web@66
|
48
|
rc-web@66
|
49 sound: function( src, options ) {
|
rc-web@66
|
50 options = options || {};
|
rc-web@66
|
51
|
rc-web@66
|
52 var pid = 0,
|
rc-web@66
|
53 events = [],
|
rc-web@66
|
54 eventsOnce = {},
|
rc-web@66
|
55 supported = buzz.isSupported();
|
rc-web@66
|
56
|
rc-web@66
|
57 // publics
|
rc-web@66
|
58 this.load = function() {
|
rc-web@66
|
59 if ( !supported ) {
|
rc-web@66
|
60 return this;
|
rc-web@66
|
61 }
|
rc-web@66
|
62
|
rc-web@66
|
63 this.sound.load();
|
rc-web@66
|
64 return this;
|
rc-web@66
|
65 };
|
rc-web@66
|
66
|
rc-web@66
|
67 this.play = function() {
|
rc-web@66
|
68 if ( !supported ) {
|
rc-web@66
|
69 return this;
|
rc-web@66
|
70 }
|
rc-web@66
|
71
|
rc-web@66
|
72 this.sound.play();
|
rc-web@66
|
73 return this;
|
rc-web@66
|
74 };
|
rc-web@66
|
75
|
rc-web@66
|
76 this.togglePlay = function() {
|
rc-web@66
|
77 if ( !supported ) {
|
rc-web@66
|
78 return this;
|
rc-web@66
|
79 }
|
rc-web@66
|
80
|
rc-web@66
|
81 if ( this.sound.paused ) {
|
rc-web@66
|
82 this.sound.play();
|
rc-web@66
|
83 } else {
|
rc-web@66
|
84 this.sound.pause();
|
rc-web@66
|
85 }
|
rc-web@66
|
86 return this;
|
rc-web@66
|
87 };
|
rc-web@66
|
88
|
rc-web@66
|
89 this.pause = function() {
|
rc-web@66
|
90 if ( !supported ) {
|
rc-web@66
|
91 return this;
|
rc-web@66
|
92 }
|
rc-web@66
|
93
|
rc-web@66
|
94 this.sound.pause();
|
rc-web@66
|
95 return this;
|
rc-web@66
|
96 };
|
rc-web@66
|
97
|
rc-web@66
|
98 this.isPaused = function() {
|
rc-web@66
|
99 if ( !supported ) {
|
rc-web@66
|
100 return null;
|
rc-web@66
|
101 }
|
rc-web@66
|
102
|
rc-web@66
|
103 return this.sound.paused;
|
rc-web@66
|
104 };
|
rc-web@66
|
105
|
rc-web@66
|
106 this.stop = function() {
|
rc-web@66
|
107 if ( !supported ) {
|
rc-web@66
|
108 return this;
|
rc-web@66
|
109 }
|
rc-web@66
|
110
|
rc-web@66
|
111 this.setTime( this.getDuration() );
|
rc-web@66
|
112 this.sound.pause();
|
rc-web@66
|
113 return this;
|
rc-web@66
|
114 };
|
rc-web@66
|
115
|
rc-web@66
|
116 this.isEnded = function() {
|
rc-web@66
|
117 if ( !supported ) {
|
rc-web@66
|
118 return null;
|
rc-web@66
|
119 }
|
rc-web@66
|
120
|
rc-web@66
|
121 return this.sound.ended;
|
rc-web@66
|
122 };
|
rc-web@66
|
123
|
rc-web@66
|
124 this.loop = function() {
|
rc-web@66
|
125 if ( !supported ) {
|
rc-web@66
|
126 return this;
|
rc-web@66
|
127 }
|
rc-web@66
|
128
|
rc-web@66
|
129 this.sound.loop = 'loop';
|
rc-web@66
|
130 this.bind( 'ended.buzzloop', function() {
|
rc-web@66
|
131 this.currentTime = 0;
|
rc-web@66
|
132 this.play();
|
rc-web@66
|
133 });
|
rc-web@66
|
134 return this;
|
rc-web@66
|
135 };
|
rc-web@66
|
136
|
rc-web@66
|
137 this.unloop = function() {
|
rc-web@66
|
138 if ( !supported ) {
|
rc-web@66
|
139 return this;
|
rc-web@66
|
140 }
|
rc-web@66
|
141
|
rc-web@66
|
142 this.sound.removeAttribute( 'loop' );
|
rc-web@66
|
143 this.unbind( 'ended.buzzloop' );
|
rc-web@66
|
144 return this;
|
rc-web@66
|
145 };
|
rc-web@66
|
146
|
rc-web@66
|
147 this.mute = function() {
|
rc-web@66
|
148 if ( !supported ) {
|
rc-web@66
|
149 return this;
|
rc-web@66
|
150 }
|
rc-web@66
|
151
|
rc-web@66
|
152 this.sound.muted = true;
|
rc-web@66
|
153 return this;
|
rc-web@66
|
154 };
|
rc-web@66
|
155
|
rc-web@66
|
156 this.unmute = function() {
|
rc-web@66
|
157 if ( !supported ) {
|
rc-web@66
|
158 return this;
|
rc-web@66
|
159 }
|
rc-web@66
|
160
|
rc-web@66
|
161 this.sound.muted = false;
|
rc-web@66
|
162 return this;
|
rc-web@66
|
163 };
|
rc-web@66
|
164
|
rc-web@66
|
165 this.toggleMute = function() {
|
rc-web@66
|
166 if ( !supported ) {
|
rc-web@66
|
167 return this;
|
rc-web@66
|
168 }
|
rc-web@66
|
169
|
rc-web@66
|
170 this.sound.muted = !this.sound.muted;
|
rc-web@66
|
171 return this;
|
rc-web@66
|
172 };
|
rc-web@66
|
173
|
rc-web@66
|
174 this.isMuted = function() {
|
rc-web@66
|
175 if ( !supported ) {
|
rc-web@66
|
176 return null;
|
rc-web@66
|
177 }
|
rc-web@66
|
178
|
rc-web@66
|
179 return this.sound.muted;
|
rc-web@66
|
180 };
|
rc-web@66
|
181
|
rc-web@66
|
182 this.setVolume = function( volume ) {
|
rc-web@66
|
183 if ( !supported ) {
|
rc-web@66
|
184 return this;
|
rc-web@66
|
185 }
|
rc-web@66
|
186
|
rc-web@66
|
187 if ( volume < 0 ) {
|
rc-web@66
|
188 volume = 0;
|
rc-web@66
|
189 }
|
rc-web@66
|
190 if ( volume > 100 ) {
|
rc-web@66
|
191 volume = 100;
|
rc-web@66
|
192 }
|
rc-web@66
|
193
|
rc-web@66
|
194 this.volume = volume;
|
rc-web@66
|
195 this.sound.volume = volume / 100;
|
rc-web@66
|
196 return this;
|
rc-web@66
|
197 };
|
rc-web@66
|
198
|
rc-web@66
|
199 this.getVolume = function() {
|
rc-web@66
|
200 if ( !supported ) {
|
rc-web@66
|
201 return this;
|
rc-web@66
|
202 }
|
rc-web@66
|
203
|
rc-web@66
|
204 return this.volume;
|
rc-web@66
|
205 };
|
rc-web@66
|
206
|
rc-web@66
|
207 this.increaseVolume = function( value ) {
|
rc-web@66
|
208 return this.setVolume( this.volume + ( value || 1 ) );
|
rc-web@66
|
209 };
|
rc-web@66
|
210
|
rc-web@66
|
211 this.decreaseVolume = function( value ) {
|
rc-web@66
|
212 return this.setVolume( this.volume - ( value || 1 ) );
|
rc-web@66
|
213 };
|
rc-web@66
|
214
|
rc-web@66
|
215 this.setTime = function( time ) {
|
rc-web@66
|
216 if ( !supported ) {
|
rc-web@66
|
217 return this;
|
rc-web@66
|
218 }
|
rc-web@66
|
219
|
rc-web@66
|
220 this.whenReady( function() {
|
rc-web@66
|
221 this.sound.currentTime = time;
|
rc-web@66
|
222 });
|
rc-web@66
|
223 return this;
|
rc-web@66
|
224 };
|
rc-web@66
|
225
|
rc-web@66
|
226 this.getTime = function() {
|
rc-web@66
|
227 if ( !supported ) {
|
rc-web@66
|
228 return null;
|
rc-web@66
|
229 }
|
rc-web@66
|
230
|
rc-web@66
|
231 var time = Math.round( this.sound.currentTime * 100 ) / 100;
|
rc-web@66
|
232 return isNaN( time ) ? buzz.defaults.placeholder : time;
|
rc-web@66
|
233 };
|
rc-web@66
|
234
|
rc-web@66
|
235 this.setPercent = function( percent ) {
|
rc-web@66
|
236 if ( !supported ) {
|
rc-web@66
|
237 return this;
|
rc-web@66
|
238 }
|
rc-web@66
|
239
|
rc-web@66
|
240 return this.setTime( buzz.fromPercent( percent, this.sound.duration ) );
|
rc-web@66
|
241 };
|
rc-web@66
|
242
|
rc-web@66
|
243 this.getPercent = function() {
|
rc-web@66
|
244 if ( !supported ) {
|
rc-web@66
|
245 return null;
|
rc-web@66
|
246 }
|
rc-web@66
|
247
|
rc-web@66
|
248 var percent = Math.round( buzz.toPercent( this.sound.currentTime, this.sound.duration ) );
|
rc-web@66
|
249 return isNaN( percent ) ? buzz.defaults.placeholder : percent;
|
rc-web@66
|
250 };
|
rc-web@66
|
251
|
rc-web@66
|
252 this.setSpeed = function( duration ) {
|
rc-web@66
|
253 if ( !supported ) {
|
rc-web@66
|
254 return this;
|
rc-web@66
|
255 }
|
rc-web@66
|
256
|
rc-web@66
|
257 this.sound.playbackRate = duration;
|
rc-web@66
|
258 };
|
rc-web@66
|
259
|
rc-web@66
|
260 this.getSpeed = function() {
|
rc-web@66
|
261 if ( !supported ) {
|
rc-web@66
|
262 return null;
|
rc-web@66
|
263 }
|
rc-web@66
|
264
|
rc-web@66
|
265 return this.sound.playbackRate;
|
rc-web@66
|
266 };
|
rc-web@66
|
267
|
rc-web@66
|
268 this.getDuration = function() {
|
rc-web@66
|
269 if ( !supported ) {
|
rc-web@66
|
270 return null;
|
rc-web@66
|
271 }
|
rc-web@66
|
272
|
rc-web@66
|
273 var duration = Math.round( this.sound.duration * 100 ) / 100;
|
rc-web@66
|
274 return isNaN( duration ) ? buzz.defaults.placeholder : duration;
|
rc-web@66
|
275 };
|
rc-web@66
|
276
|
rc-web@66
|
277 this.getPlayed = function() {
|
rc-web@66
|
278 if ( !supported ) {
|
rc-web@66
|
279 return null;
|
rc-web@66
|
280 }
|
rc-web@66
|
281
|
rc-web@66
|
282 return timerangeToArray( this.sound.played );
|
rc-web@66
|
283 };
|
rc-web@66
|
284
|
rc-web@66
|
285 this.getBuffered = function() {
|
rc-web@66
|
286 if ( !supported ) {
|
rc-web@66
|
287 return null;
|
rc-web@66
|
288 }
|
rc-web@66
|
289
|
rc-web@66
|
290 return timerangeToArray( this.sound.buffered );
|
rc-web@66
|
291 };
|
rc-web@66
|
292
|
rc-web@66
|
293 this.getSeekable = function() {
|
rc-web@66
|
294 if ( !supported ) {
|
rc-web@66
|
295 return null;
|
rc-web@66
|
296 }
|
rc-web@66
|
297
|
rc-web@66
|
298 return timerangeToArray( this.sound.seekable );
|
rc-web@66
|
299 };
|
rc-web@66
|
300
|
rc-web@66
|
301 this.getErrorCode = function() {
|
rc-web@66
|
302 if ( supported && this.sound.error ) {
|
rc-web@66
|
303 return this.sound.error.code;
|
rc-web@66
|
304 }
|
rc-web@66
|
305 return 0;
|
rc-web@66
|
306 };
|
rc-web@66
|
307
|
rc-web@66
|
308 this.getErrorMessage = function() {
|
rc-web@66
|
309 if ( !supported ) {
|
rc-web@66
|
310 return null;
|
rc-web@66
|
311 }
|
rc-web@66
|
312
|
rc-web@66
|
313 switch( this.getErrorCode() ) {
|
rc-web@66
|
314 case 1:
|
rc-web@66
|
315 return 'MEDIA_ERR_ABORTED';
|
rc-web@66
|
316 case 2:
|
rc-web@66
|
317 return 'MEDIA_ERR_NETWORK';
|
rc-web@66
|
318 case 3:
|
rc-web@66
|
319 return 'MEDIA_ERR_DECODE';
|
rc-web@66
|
320 case 4:
|
rc-web@66
|
321 return 'MEDIA_ERR_SRC_NOT_SUPPORTED';
|
rc-web@66
|
322 default:
|
rc-web@66
|
323 return null;
|
rc-web@66
|
324 }
|
rc-web@66
|
325 };
|
rc-web@66
|
326
|
rc-web@66
|
327 this.getStateCode = function() {
|
rc-web@66
|
328 if ( !supported ) {
|
rc-web@66
|
329 return null;
|
rc-web@66
|
330 }
|
rc-web@66
|
331
|
rc-web@66
|
332 return this.sound.readyState;
|
rc-web@66
|
333 };
|
rc-web@66
|
334
|
rc-web@66
|
335 this.getStateMessage = function() {
|
rc-web@66
|
336 if ( !supported ) {
|
rc-web@66
|
337 return null;
|
rc-web@66
|
338 }
|
rc-web@66
|
339
|
rc-web@66
|
340 switch( this.getStateCode() ) {
|
rc-web@66
|
341 case 0:
|
rc-web@66
|
342 return 'HAVE_NOTHING';
|
rc-web@66
|
343 case 1:
|
rc-web@66
|
344 return 'HAVE_METADATA';
|
rc-web@66
|
345 case 2:
|
rc-web@66
|
346 return 'HAVE_CURRENT_DATA';
|
rc-web@66
|
347 case 3:
|
rc-web@66
|
348 return 'HAVE_FUTURE_DATA';
|
rc-web@66
|
349 case 4:
|
rc-web@66
|
350 return 'HAVE_ENOUGH_DATA';
|
rc-web@66
|
351 default:
|
rc-web@66
|
352 return null;
|
rc-web@66
|
353 }
|
rc-web@66
|
354 };
|
rc-web@66
|
355
|
rc-web@66
|
356 this.getNetworkStateCode = function() {
|
rc-web@66
|
357 if ( !supported ) {
|
rc-web@66
|
358 return null;
|
rc-web@66
|
359 }
|
rc-web@66
|
360
|
rc-web@66
|
361 return this.sound.networkState;
|
rc-web@66
|
362 };
|
rc-web@66
|
363
|
rc-web@66
|
364 this.getNetworkStateMessage = function() {
|
rc-web@66
|
365 if ( !supported ) {
|
rc-web@66
|
366 return null;
|
rc-web@66
|
367 }
|
rc-web@66
|
368
|
rc-web@66
|
369 switch( this.getNetworkStateCode() ) {
|
rc-web@66
|
370 case 0:
|
rc-web@66
|
371 return 'NETWORK_EMPTY';
|
rc-web@66
|
372 case 1:
|
rc-web@66
|
373 return 'NETWORK_IDLE';
|
rc-web@66
|
374 case 2:
|
rc-web@66
|
375 return 'NETWORK_LOADING';
|
rc-web@66
|
376 case 3:
|
rc-web@66
|
377 return 'NETWORK_NO_SOURCE';
|
rc-web@66
|
378 default:
|
rc-web@66
|
379 return null;
|
rc-web@66
|
380 }
|
rc-web@66
|
381 };
|
rc-web@66
|
382
|
rc-web@66
|
383 this.set = function( key, value ) {
|
rc-web@66
|
384 if ( !supported ) {
|
rc-web@66
|
385 return this;
|
rc-web@66
|
386 }
|
rc-web@66
|
387
|
rc-web@66
|
388 this.sound[ key ] = value;
|
rc-web@66
|
389 return this;
|
rc-web@66
|
390 };
|
rc-web@66
|
391
|
rc-web@66
|
392 this.get = function( key ) {
|
rc-web@66
|
393 if ( !supported ) {
|
rc-web@66
|
394 return null;
|
rc-web@66
|
395 }
|
rc-web@66
|
396
|
rc-web@66
|
397 return key ? this.sound[ key ] : this.sound;
|
rc-web@66
|
398 };
|
rc-web@66
|
399
|
rc-web@66
|
400 this.bind = function( types, func ) {
|
rc-web@66
|
401 if ( !supported ) {
|
rc-web@66
|
402 return this;
|
rc-web@66
|
403 }
|
rc-web@66
|
404
|
rc-web@66
|
405 types = types.split( ' ' );
|
rc-web@66
|
406
|
rc-web@66
|
407 var that = this,
|
rc-web@66
|
408 efunc = function( e ) { func.call( that, e ); };
|
rc-web@66
|
409
|
rc-web@66
|
410 for( var t = 0; t < types.length; t++ ) {
|
rc-web@66
|
411 var type = types[ t ],
|
rc-web@66
|
412 idx = type;
|
rc-web@66
|
413 type = idx.split( '.' )[ 0 ];
|
rc-web@66
|
414
|
rc-web@66
|
415 events.push( { idx: idx, func: efunc } );
|
rc-web@66
|
416 this.sound.addEventListener( type, efunc, true );
|
rc-web@66
|
417 }
|
rc-web@66
|
418 return this;
|
rc-web@66
|
419 };
|
rc-web@66
|
420
|
rc-web@66
|
421 this.unbind = function( types ) {
|
rc-web@66
|
422 if ( !supported ) {
|
rc-web@66
|
423 return this;
|
rc-web@66
|
424 }
|
rc-web@66
|
425
|
rc-web@66
|
426 types = types.split( ' ' );
|
rc-web@66
|
427
|
rc-web@66
|
428 for( var t = 0; t < types.length; t++ ) {
|
rc-web@66
|
429 var idx = types[ t ],
|
rc-web@66
|
430 type = idx.split( '.' )[ 0 ];
|
rc-web@66
|
431
|
rc-web@66
|
432 for( var i = 0; i < events.length; i++ ) {
|
rc-web@66
|
433 var namespace = events[ i ].idx.split( '.' );
|
rc-web@66
|
434 if ( events[ i ].idx == idx || ( namespace[ 1 ] && namespace[ 1 ] == idx.replace( '.', '' ) ) ) {
|
rc-web@66
|
435 this.sound.removeEventListener( type, events[ i ].func, true );
|
rc-web@66
|
436 delete events[ i ];
|
rc-web@66
|
437 }
|
rc-web@66
|
438 }
|
rc-web@66
|
439 }
|
rc-web@66
|
440 return this;
|
rc-web@66
|
441 };
|
rc-web@66
|
442
|
rc-web@66
|
443 this.bindOnce = function( type, func ) {
|
rc-web@66
|
444 if ( !supported ) {
|
rc-web@66
|
445 return this;
|
rc-web@66
|
446 }
|
rc-web@66
|
447
|
rc-web@66
|
448 var that = this;
|
rc-web@66
|
449
|
rc-web@66
|
450 eventsOnce[ pid++ ] = false;
|
rc-web@66
|
451 this.bind( pid + type, function() {
|
rc-web@66
|
452 if ( !eventsOnce[ pid ] ) {
|
rc-web@66
|
453 eventsOnce[ pid ] = true;
|
rc-web@66
|
454 func.call( that );
|
rc-web@66
|
455 }
|
rc-web@66
|
456 that.unbind( pid + type );
|
rc-web@66
|
457 });
|
rc-web@66
|
458 };
|
rc-web@66
|
459
|
rc-web@66
|
460 this.trigger = function( types ) {
|
rc-web@66
|
461 if ( !supported ) {
|
rc-web@66
|
462 return this;
|
rc-web@66
|
463 }
|
rc-web@66
|
464
|
rc-web@66
|
465 types = types.split( ' ' );
|
rc-web@66
|
466
|
rc-web@66
|
467 for( var t = 0; t < types.length; t++ ) {
|
rc-web@66
|
468 var idx = types[ t ];
|
rc-web@66
|
469
|
rc-web@66
|
470 for( var i = 0; i < events.length; i++ ) {
|
rc-web@66
|
471 var eventType = events[ i ].idx.split( '.' );
|
rc-web@66
|
472 if ( events[ i ].idx == idx || ( eventType[ 0 ] && eventType[ 0 ] == idx.replace( '.', '' ) ) ) {
|
rc-web@66
|
473 var evt = document.createEvent('HTMLEvents');
|
rc-web@66
|
474 evt.initEvent( eventType[ 0 ], false, true );
|
rc-web@66
|
475 this.sound.dispatchEvent( evt );
|
rc-web@66
|
476 }
|
rc-web@66
|
477 }
|
rc-web@66
|
478 }
|
rc-web@66
|
479 return this;
|
rc-web@66
|
480 };
|
rc-web@66
|
481
|
rc-web@66
|
482 this.fadeTo = function( to, duration, callback ) {
|
rc-web@66
|
483 if ( !supported ) {
|
rc-web@66
|
484 return this;
|
rc-web@66
|
485 }
|
rc-web@66
|
486
|
rc-web@66
|
487 if ( duration instanceof Function ) {
|
rc-web@66
|
488 callback = duration;
|
rc-web@66
|
489 duration = buzz.defaults.duration;
|
rc-web@66
|
490 } else {
|
rc-web@66
|
491 duration = duration || buzz.defaults.duration;
|
rc-web@66
|
492 }
|
rc-web@66
|
493
|
rc-web@66
|
494 var from = this.volume,
|
rc-web@66
|
495 delay = duration / Math.abs( from - to ),
|
rc-web@66
|
496 that = this;
|
rc-web@66
|
497 this.play();
|
rc-web@66
|
498
|
rc-web@66
|
499 function doFade() {
|
rc-web@66
|
500 setTimeout( function() {
|
rc-web@66
|
501 if ( from < to && that.volume < to ) {
|
rc-web@66
|
502 that.setVolume( that.volume += 1 );
|
rc-web@66
|
503 doFade();
|
rc-web@66
|
504 } else if ( from > to && that.volume > to ) {
|
rc-web@66
|
505 that.setVolume( that.volume -= 1 );
|
rc-web@66
|
506 doFade();
|
rc-web@66
|
507 } else if ( callback instanceof Function ) {
|
rc-web@66
|
508 callback.apply( that );
|
rc-web@66
|
509 }
|
rc-web@66
|
510 }, delay );
|
rc-web@66
|
511 }
|
rc-web@66
|
512 this.whenReady( function() {
|
rc-web@66
|
513 doFade();
|
rc-web@66
|
514 });
|
rc-web@66
|
515
|
rc-web@66
|
516 return this;
|
rc-web@66
|
517 };
|
rc-web@66
|
518
|
rc-web@66
|
519 this.fadeIn = function( duration, callback ) {
|
rc-web@66
|
520 if ( !supported ) {
|
rc-web@66
|
521 return this;
|
rc-web@66
|
522 }
|
rc-web@66
|
523
|
rc-web@66
|
524 return this.setVolume(0).fadeTo( 100, duration, callback );
|
rc-web@66
|
525 };
|
rc-web@66
|
526
|
rc-web@66
|
527 this.fadeOut = function( duration, callback ) {
|
rc-web@66
|
528 if ( !supported ) {
|
rc-web@66
|
529 return this;
|
rc-web@66
|
530 }
|
rc-web@66
|
531
|
rc-web@66
|
532 return this.fadeTo( 0, duration, callback );
|
rc-web@66
|
533 };
|
rc-web@66
|
534
|
rc-web@66
|
535 this.fadeWith = function( sound, duration ) {
|
rc-web@66
|
536 if ( !supported ) {
|
rc-web@66
|
537 return this;
|
rc-web@66
|
538 }
|
rc-web@66
|
539
|
rc-web@66
|
540 this.fadeOut( duration, function() {
|
rc-web@66
|
541 this.stop();
|
rc-web@66
|
542 });
|
rc-web@66
|
543
|
rc-web@66
|
544 sound.play().fadeIn( duration );
|
rc-web@66
|
545
|
rc-web@66
|
546 return this;
|
rc-web@66
|
547 };
|
rc-web@66
|
548
|
rc-web@66
|
549 this.whenReady = function( func ) {
|
rc-web@66
|
550 if ( !supported ) {
|
rc-web@66
|
551 return null;
|
rc-web@66
|
552 }
|
rc-web@66
|
553
|
rc-web@66
|
554 var that = this;
|
rc-web@66
|
555 if ( this.sound.readyState === 0 ) {
|
rc-web@66
|
556 this.bind( 'canplay.buzzwhenready', function() {
|
rc-web@66
|
557 func.call( that );
|
rc-web@66
|
558 });
|
rc-web@66
|
559 } else {
|
rc-web@66
|
560 func.call( that );
|
rc-web@66
|
561 }
|
rc-web@66
|
562 };
|
rc-web@66
|
563
|
rc-web@66
|
564 // privates
|
rc-web@66
|
565 function timerangeToArray( timeRange ) {
|
rc-web@66
|
566 var array = [],
|
rc-web@66
|
567 length = timeRange.length - 1;
|
rc-web@66
|
568
|
rc-web@66
|
569 for( var i = 0; i <= length; i++ ) {
|
rc-web@66
|
570 array.push({
|
rc-web@66
|
571 start: timeRange.start( length ),
|
rc-web@66
|
572 end: timeRange.end( length )
|
rc-web@66
|
573 });
|
rc-web@66
|
574 }
|
rc-web@66
|
575 return array;
|
rc-web@66
|
576 }
|
rc-web@66
|
577
|
rc-web@66
|
578 function getExt( filename ) {
|
rc-web@66
|
579 return filename.split('.').pop();
|
rc-web@66
|
580 }
|
rc-web@66
|
581
|
rc-web@66
|
582 function addSource( sound, src ) {
|
rc-web@66
|
583 var source = document.createElement( 'source' );
|
rc-web@66
|
584 source.src = src;
|
rc-web@66
|
585 if ( buzz.types[ getExt( src ) ] ) {
|
rc-web@66
|
586 source.type = buzz.types[ getExt( src ) ];
|
rc-web@66
|
587 }
|
rc-web@66
|
588 sound.appendChild( source );
|
rc-web@66
|
589 }
|
rc-web@66
|
590
|
rc-web@66
|
591 // init
|
rc-web@66
|
592 if ( supported ) {
|
rc-web@66
|
593
|
rc-web@66
|
594 for(var i in buzz.defaults ) {
|
rc-web@66
|
595 if(buzz.defaults.hasOwnProperty(i)) {
|
rc-web@66
|
596 options[ i ] = options[ i ] || buzz.defaults[ i ];
|
rc-web@66
|
597 }
|
rc-web@66
|
598 }
|
rc-web@66
|
599
|
rc-web@66
|
600 this.sound = document.createElement( 'audio' );
|
rc-web@66
|
601
|
rc-web@66
|
602 if ( src instanceof Array ) {
|
rc-web@66
|
603 for( var j in src ) {
|
rc-web@66
|
604 if(src.hasOwnProperty(j)) {
|
rc-web@66
|
605 addSource( this.sound, src[ j ] );
|
rc-web@66
|
606 }
|
rc-web@66
|
607 }
|
rc-web@66
|
608 } else if ( options.formats.length ) {
|
rc-web@66
|
609 for( var k in options.formats ) {
|
rc-web@66
|
610 if(options.formats.hasOwnProperty(k)) {
|
rc-web@66
|
611 addSource( this.sound, src + '.' + options.formats[ k ] );
|
rc-web@66
|
612 }
|
rc-web@66
|
613 }
|
rc-web@66
|
614 } else {
|
rc-web@66
|
615 addSource( this.sound, src );
|
rc-web@66
|
616 }
|
rc-web@66
|
617
|
rc-web@66
|
618 if ( options.loop ) {
|
rc-web@66
|
619 this.loop();
|
rc-web@66
|
620 }
|
rc-web@66
|
621
|
rc-web@66
|
622 if ( options.autoplay ) {
|
rc-web@66
|
623 this.sound.autoplay = 'autoplay';
|
rc-web@66
|
624 }
|
rc-web@66
|
625
|
rc-web@66
|
626 if ( options.preload === true ) {
|
rc-web@66
|
627 this.sound.preload = 'auto';
|
rc-web@66
|
628 } else if ( options.preload === false ) {
|
rc-web@66
|
629 this.sound.preload = 'none';
|
rc-web@66
|
630 } else {
|
rc-web@66
|
631 this.sound.preload = options.preload;
|
rc-web@66
|
632 }
|
rc-web@66
|
633
|
rc-web@66
|
634 this.setVolume( options.volume );
|
rc-web@66
|
635
|
rc-web@66
|
636 buzz.sounds.push( this );
|
rc-web@66
|
637 }
|
rc-web@66
|
638 },
|
rc-web@66
|
639
|
rc-web@66
|
640 group: function( sounds ) {
|
rc-web@66
|
641 sounds = argsToArray( sounds, arguments );
|
rc-web@66
|
642
|
rc-web@66
|
643 // publics
|
rc-web@66
|
644 this.getSounds = function() {
|
rc-web@66
|
645 return sounds;
|
rc-web@66
|
646 };
|
rc-web@66
|
647
|
rc-web@66
|
648 this.add = function( soundArray ) {
|
rc-web@66
|
649 soundArray = argsToArray( soundArray, arguments );
|
rc-web@66
|
650 for( var a = 0; a < soundArray.length; a++ ) {
|
rc-web@66
|
651 sounds.push( soundArray[ a ] );
|
rc-web@66
|
652 }
|
rc-web@66
|
653 };
|
rc-web@66
|
654
|
rc-web@66
|
655 this.remove = function( soundArray ) {
|
rc-web@66
|
656 soundArray = argsToArray( soundArray, arguments );
|
rc-web@66
|
657 for( var a = 0; a < soundArray.length; a++ ) {
|
rc-web@66
|
658 for( var i = 0; i < sounds.length; i++ ) {
|
rc-web@66
|
659 if ( sounds[ i ] == soundArray[ a ] ) {
|
rc-web@66
|
660 delete sounds[ i ];
|
rc-web@66
|
661 break;
|
rc-web@66
|
662 }
|
rc-web@66
|
663 }
|
rc-web@66
|
664 }
|
rc-web@66
|
665 };
|
rc-web@66
|
666
|
rc-web@66
|
667 this.load = function() {
|
rc-web@66
|
668 fn( 'load' );
|
rc-web@66
|
669 return this;
|
rc-web@66
|
670 };
|
rc-web@66
|
671
|
rc-web@66
|
672 this.play = function() {
|
rc-web@66
|
673 fn( 'play' );
|
rc-web@66
|
674 return this;
|
rc-web@66
|
675 };
|
rc-web@66
|
676
|
rc-web@66
|
677 this.togglePlay = function( ) {
|
rc-web@66
|
678 fn( 'togglePlay' );
|
rc-web@66
|
679 return this;
|
rc-web@66
|
680 };
|
rc-web@66
|
681
|
rc-web@66
|
682 this.pause = function( time ) {
|
rc-web@66
|
683 fn( 'pause', time );
|
rc-web@66
|
684 return this;
|
rc-web@66
|
685 };
|
rc-web@66
|
686
|
rc-web@66
|
687 this.stop = function() {
|
rc-web@66
|
688 fn( 'stop' );
|
rc-web@66
|
689 return this;
|
rc-web@66
|
690 };
|
rc-web@66
|
691
|
rc-web@66
|
692 this.mute = function() {
|
rc-web@66
|
693 fn( 'mute' );
|
rc-web@66
|
694 return this;
|
rc-web@66
|
695 };
|
rc-web@66
|
696
|
rc-web@66
|
697 this.unmute = function() {
|
rc-web@66
|
698 fn( 'unmute' );
|
rc-web@66
|
699 return this;
|
rc-web@66
|
700 };
|
rc-web@66
|
701
|
rc-web@66
|
702 this.toggleMute = function() {
|
rc-web@66
|
703 fn( 'toggleMute' );
|
rc-web@66
|
704 return this;
|
rc-web@66
|
705 };
|
rc-web@66
|
706
|
rc-web@66
|
707 this.setVolume = function( volume ) {
|
rc-web@66
|
708 fn( 'setVolume', volume );
|
rc-web@66
|
709 return this;
|
rc-web@66
|
710 };
|
rc-web@66
|
711
|
rc-web@66
|
712 this.increaseVolume = function( value ) {
|
rc-web@66
|
713 fn( 'increaseVolume', value );
|
rc-web@66
|
714 return this;
|
rc-web@66
|
715 };
|
rc-web@66
|
716
|
rc-web@66
|
717 this.decreaseVolume = function( value ) {
|
rc-web@66
|
718 fn( 'decreaseVolume', value );
|
rc-web@66
|
719 return this;
|
rc-web@66
|
720 };
|
rc-web@66
|
721
|
rc-web@66
|
722 this.loop = function() {
|
rc-web@66
|
723 fn( 'loop' );
|
rc-web@66
|
724 return this;
|
rc-web@66
|
725 };
|
rc-web@66
|
726
|
rc-web@66
|
727 this.unloop = function() {
|
rc-web@66
|
728 fn( 'unloop' );
|
rc-web@66
|
729 return this;
|
rc-web@66
|
730 };
|
rc-web@66
|
731
|
rc-web@66
|
732 this.setTime = function( time ) {
|
rc-web@66
|
733 fn( 'setTime', time );
|
rc-web@66
|
734 return this;
|
rc-web@66
|
735 };
|
rc-web@66
|
736
|
rc-web@66
|
737 this.setduration = function( duration ) {
|
rc-web@66
|
738 fn( 'setduration', duration );
|
rc-web@66
|
739 return this;
|
rc-web@66
|
740 };
|
rc-web@66
|
741
|
rc-web@66
|
742 this.set = function( key, value ) {
|
rc-web@66
|
743 fn( 'set', key, value );
|
rc-web@66
|
744 return this;
|
rc-web@66
|
745 };
|
rc-web@66
|
746
|
rc-web@66
|
747 this.bind = function( type, func ) {
|
rc-web@66
|
748 fn( 'bind', type, func );
|
rc-web@66
|
749 return this;
|
rc-web@66
|
750 };
|
rc-web@66
|
751
|
rc-web@66
|
752 this.unbind = function( type ) {
|
rc-web@66
|
753 fn( 'unbind', type );
|
rc-web@66
|
754 return this;
|
rc-web@66
|
755 };
|
rc-web@66
|
756
|
rc-web@66
|
757 this.bindOnce = function( type, func ) {
|
rc-web@66
|
758 fn( 'bindOnce', type, func );
|
rc-web@66
|
759 return this;
|
rc-web@66
|
760 };
|
rc-web@66
|
761
|
rc-web@66
|
762 this.trigger = function( type ) {
|
rc-web@66
|
763 fn( 'trigger', type );
|
rc-web@66
|
764 return this;
|
rc-web@66
|
765 };
|
rc-web@66
|
766
|
rc-web@66
|
767 this.fade = function( from, to, duration, callback ) {
|
rc-web@66
|
768 fn( 'fade', from, to, duration, callback );
|
rc-web@66
|
769 return this;
|
rc-web@66
|
770 };
|
rc-web@66
|
771
|
rc-web@66
|
772 this.fadeIn = function( duration, callback ) {
|
rc-web@66
|
773 fn( 'fadeIn', duration, callback );
|
rc-web@66
|
774 return this;
|
rc-web@66
|
775 };
|
rc-web@66
|
776
|
rc-web@66
|
777 this.fadeOut = function( duration, callback ) {
|
rc-web@66
|
778 fn( 'fadeOut', duration, callback );
|
rc-web@66
|
779 return this;
|
rc-web@66
|
780 };
|
rc-web@66
|
781
|
rc-web@66
|
782 // privates
|
rc-web@66
|
783 function fn() {
|
rc-web@66
|
784 var args = argsToArray( null, arguments ),
|
rc-web@66
|
785 func = args.shift();
|
rc-web@66
|
786
|
rc-web@66
|
787 for( var i = 0; i < sounds.length; i++ ) {
|
rc-web@66
|
788 sounds[ i ][ func ].apply( sounds[ i ], args );
|
rc-web@66
|
789 }
|
rc-web@66
|
790 }
|
rc-web@66
|
791
|
rc-web@66
|
792 function argsToArray( array, args ) {
|
rc-web@66
|
793 return ( array instanceof Array ) ? array : Array.prototype.slice.call( args );
|
rc-web@66
|
794 }
|
rc-web@66
|
795 },
|
rc-web@66
|
796
|
rc-web@66
|
797 all: function() {
|
rc-web@66
|
798 return new buzz.group( buzz.sounds );
|
rc-web@66
|
799 },
|
rc-web@66
|
800
|
rc-web@66
|
801 isSupported: function() {
|
rc-web@66
|
802 return !!buzz.el.canPlayType;
|
rc-web@66
|
803 },
|
rc-web@66
|
804
|
rc-web@66
|
805 isOGGSupported: function() {
|
rc-web@66
|
806 return !!buzz.el.canPlayType && buzz.el.canPlayType( 'audio/ogg; codecs="vorbis"' );
|
rc-web@66
|
807 },
|
rc-web@66
|
808
|
rc-web@66
|
809 isWAVSupported: function() {
|
rc-web@66
|
810 return !!buzz.el.canPlayType && buzz.el.canPlayType( 'audio/wav; codecs="1"' );
|
rc-web@66
|
811 },
|
rc-web@66
|
812
|
rc-web@66
|
813 isMP3Supported: function() {
|
rc-web@66
|
814 return !!buzz.el.canPlayType && buzz.el.canPlayType( 'audio/mpeg;' );
|
rc-web@66
|
815 },
|
rc-web@66
|
816
|
rc-web@66
|
817 isAACSupported: function() {
|
rc-web@66
|
818 return !!buzz.el.canPlayType && ( buzz.el.canPlayType( 'audio/x-m4a;' ) || buzz.el.canPlayType( 'audio/aac;' ) );
|
rc-web@66
|
819 },
|
rc-web@66
|
820
|
rc-web@66
|
821 toTimer: function( time, withHours ) {
|
rc-web@66
|
822 var h, m, s;
|
rc-web@66
|
823 h = Math.floor( time / 3600 );
|
rc-web@66
|
824 h = isNaN( h ) ? '--' : ( h >= 10 ) ? h : '0' + h;
|
rc-web@66
|
825 m = withHours ? Math.floor( time / 60 % 60 ) : Math.floor( time / 60 );
|
rc-web@66
|
826 m = isNaN( m ) ? '--' : ( m >= 10 ) ? m : '0' + m;
|
rc-web@66
|
827 s = Math.floor( time % 60 );
|
rc-web@66
|
828 s = isNaN( s ) ? '--' : ( s >= 10 ) ? s : '0' + s;
|
rc-web@66
|
829 return withHours ? h + ':' + m + ':' + s : m + ':' + s;
|
rc-web@66
|
830 },
|
rc-web@66
|
831
|
rc-web@66
|
832 fromTimer: function( time ) {
|
rc-web@66
|
833 var splits = time.toString().split( ':' );
|
rc-web@66
|
834 if ( splits && splits.length == 3 ) {
|
rc-web@66
|
835 time = ( parseInt( splits[ 0 ], 10 ) * 3600 ) + ( parseInt(splits[ 1 ], 10 ) * 60 ) + parseInt( splits[ 2 ], 10 );
|
rc-web@66
|
836 }
|
rc-web@66
|
837 if ( splits && splits.length == 2 ) {
|
rc-web@66
|
838 time = ( parseInt( splits[ 0 ], 10 ) * 60 ) + parseInt( splits[ 1 ], 10 );
|
rc-web@66
|
839 }
|
rc-web@66
|
840 return time;
|
rc-web@66
|
841 },
|
rc-web@66
|
842
|
rc-web@66
|
843 toPercent: function( value, total, decimal ) {
|
rc-web@66
|
844 var r = Math.pow( 10, decimal || 0 );
|
rc-web@66
|
845
|
rc-web@66
|
846 return Math.round( ( ( value * 100 ) / total ) * r ) / r;
|
rc-web@66
|
847 },
|
rc-web@66
|
848
|
rc-web@66
|
849 fromPercent: function( percent, total, decimal ) {
|
rc-web@66
|
850 var r = Math.pow( 10, decimal || 0 );
|
rc-web@66
|
851
|
rc-web@66
|
852 return Math.round( ( ( total / 100 ) * percent ) * r ) / r;
|
rc-web@66
|
853 }
|
rc-web@66
|
854 };
|