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