123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- // ----------------------------------------------------------------------------
- // Buzz, a Javascript HTML5 Audio library
- // v 1.0.4 beta
- // Licensed under the MIT license.
- // http://buzz.jaysalvat.com/
- // ----------------------------------------------------------------------------
- // Copyright (C) 2011 Jay Salvat
- // http://jaysalvat.com/
- // ----------------------------------------------------------------------------
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files ( the "Software" ), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- // ----------------------------------------------------------------------------
- var buzz = {
- defaults: {
- autoplay: false,
- duration: 5000,
- formats: [],
- loop: false,
- placeholder: '--',
- preload: 'metadata',
- volume: 80
- },
- types: {
- 'mp3': 'audio/mpeg',
- 'ogg': 'audio/ogg',
- 'wav': 'audio/wav',
- 'aac': 'audio/aac',
- 'm4a': 'audio/x-m4a'
- },
- sounds: [],
- el: document.createElement( 'audio' ),
- sound: function( src, options ) {
- var options = options || {},
- pid = 0,
- events = [],
- eventsOnce = {},
- supported = buzz.isSupported();
- // publics
- this.load = function() {
- if ( !supported ) return this;
- this.sound.load();
- return this;
- }
- this.play = function() {
- if ( !supported ) return this;
- this.sound.play();
- return this;
- }
- this.togglePlay = function() {
- if ( !supported ) return this;
- if ( this.sound.paused ) {
- this.sound.play();
- } else {
- this.sound.pause();
- }
- return this;
- }
- this.pause = function() {
- if ( !supported ) return this;
- this.sound.pause();
- return this;
- }
- this.isPaused = function() {
- if ( !supported ) return null;
- return this.sound.paused;
- }
- this.stop = function() {
- if ( !supported ) return this;
- this.setTime( this.getDuration() );
- this.sound.pause();
- return this;
- }
- this.isEnded = function() {
- if ( !supported ) return null;
- return this.sound.ended;
- }
- this.loop = function() {
- if ( !supported ) return this;
- this.sound.loop = 'loop';
- this.bind( 'ended.buzzloop', function() {
- this.currentTime = 0;
- this.play();
- });
- return this;
- }
- this.unloop = function() {
- if ( !supported ) return this;
- this.sound.removeAttribute( 'loop' );
- this.unbind( 'ended.buzzloop' );
- return this;
- }
- this.mute = function() {
- if ( !supported ) return this;
- this.sound.muted = true;
- return this;
- }
- this.unmute = function() {
- if ( !supported ) return this;
- this.sound.muted = false;
- return this;
- }
- this.toggleMute = function() {
- if ( !supported ) return this;
- this.sound.muted = !this.sound.muted;
- return this;
- }
- this.isMuted = function() {
- if ( !supported ) return null;
- return this.sound.muted;
- }
- this.setVolume = function( volume ) {
- if ( !supported ) return this;
- if ( volume < 0 ) volume = 0;
- if ( volume > 100 ) volume = 100;
- this.volume = volume;
- this.sound.volume = volume / 100;
- return this;
- },
- this.getVolume = function() {
- if ( !supported ) return this;
- return this.volume;
- }
- this.increaseVolume = function( value ) {
- return this.setVolume( this.volume + ( value || 1 ) );
- }
- this.decreaseVolume = function( value ) {
- return this.setVolume( this.volume - ( value || 1 ) );
- }
- this.setTime = function( time ) {
- if ( !supported ) return this;
- this.whenReady( function() {
- this.sound.currentTime = time;
- });
- return this;
- }
- this.getTime = function() {
- if ( !supported ) return null;
- var time = Math.round( this.sound.currentTime * 100 ) / 100;
- return isNaN( time ) ? buzz.defaults.placeholder : time;
- }
- this.setPercent = function( percent ) {
- if ( !supported ) return this;
- return this.setTime( buzz.fromPercent( percent, this.sound.duration ) );
- }
- this.getPercent = function() {
- if ( !supported ) return null;
- var percent = Math.round( buzz.toPercent( this.sound.currentTime, this.sound.duration ) );
- return isNaN( percent ) ? buzz.defaults.placeholder : percent;
- }
- this.setSpeed = function( duration ) {
- if ( !supported ) return this;
- this.sound.playbackRate = duration;
- }
- this.getSpeed = function() {
- if ( !supported ) return null;
- return this.sound.playbackRate;
- }
- this.getDuration = function() {
- if ( !supported ) return null;
- var duration = Math.round( this.sound.duration * 100 ) / 100;
- return isNaN( duration ) ? buzz.defaults.placeholder : duration;
- }
- this.getPlayed = function() {
- if ( !supported ) return null;
- return timerangeToArray( this.sound.played );
- }
- this.getBuffered = function() {
- if ( !supported ) return null;
- return timerangeToArray( this.sound.buffered );
- }
- this.getSeekable = function() {
- if ( !supported ) return null;
- return timerangeToArray( this.sound.seekable );
- }
- this.getErrorCode = function() {
- if ( supported && this.sound.error ) {
- return this.sound.error.code;
- }
- return 0;
- }
- this.getErrorMessage = function() {
- if ( !supported ) return null;
- switch( this.getErrorCode() ) {
- case 1:
- return 'MEDIA_ERR_ABORTED';
- case 2:
- return 'MEDIA_ERR_NETWORK';
- case 3:
- return 'MEDIA_ERR_DECODE';
- case 4:
- return 'MEDIA_ERR_SRC_NOT_SUPPORTED';
- default:
- return null;
- }
- }
- this.getStateCode = function() {
- if ( !supported ) return null;
- return this.sound.readyState;
- }
- this.getStateMessage = function() {
- if ( !supported ) return null;
- switch( this.getStateCode() ) {
- case 0:
- return 'HAVE_NOTHING';
- case 1:
- return 'HAVE_METADATA';
- case 2:
- return 'HAVE_CURRENT_DATA';
- case 3:
- return 'HAVE_FUTURE_DATA';
- case 4:
- return 'HAVE_ENOUGH_DATA';
- default:
- return null;
- }
- }
- this.getNetworkStateCode = function() {
- if ( !supported ) return null;
- return this.sound.networkState;
- }
- this.getNetworkStateMessage = function() {
- if ( !supported ) return null;
- switch( this.getNetworkStateCode() ) {
- case 0:
- return 'NETWORK_EMPTY';
- case 1:
- return 'NETWORK_IDLE';
- case 2:
- return 'NETWORK_LOADING';
- case 3:
- return 'NETWORK_NO_SOURCE';
- default:
- return null;
- }
- }
- this.set = function( key, value ) {
- if ( !supported ) return this;
- this.sound[ key ] = value;
- return this;
- }
- this.get = function( key ) {
- if ( !supported ) return null;
- return key ? this.sound[ key ] : this.sound;
- }
- this.bind = function( types, func ) {
- if ( !supported ) return this;
- var that = this,
- types = types.split( ' ' ),
- efunc = function( e ) { func.call( that, e ) };
- for( var t = 0; t < types.length; t++ ) {
- var type = types[ t ],
- idx = type;
- type = idx.split( '.' )[ 0 ];
- events.push( { idx: idx, func: efunc } );
- this.sound.addEventListener( type, efunc, true );
- }
- return this;
- }
- this.unbind = function( types ) {
- if ( !supported ) return this;
- var types = types.split( ' ' );
- for( var t = 0; t < types.length; t++ ) {
- var idx = types[ t ];
- type = idx.split( '.' )[ 0 ];
- for( var i = 0; i < events.length; i++ ) {
- var namespace = events[ i ].idx.split( '.' );
- if ( events[ i ].idx == idx || ( namespace[ 1 ] && namespace[ 1 ] == idx.replace( '.', '' ) ) ) {
- this.sound.removeEventListener( type, events[ i ].func, true );
- delete events[ i ];
- }
- }
- }
- return this;
- }
- this.bindOnce = function( type, func ) {
- if ( !supported ) return this;
- var that = this;
- eventsOnce[ pid++ ] = false;
- this.bind( pid + type, function() {
- if ( !eventsOnce[ pid ] ) {
- eventsOnce[ pid ] = true;
- func.call( that );
- }
- that.unbind( pid + type );
- });
- }
- this.trigger = function( types ) {
- if ( !supported ) return this;
- var types = types.split( ' ' );
- for( var t = 0; t < types.length; t++ ) {
- var idx = types[ t ];
- for( var i = 0; i < events.length; i++ ) {
- var eventType = events[ i ].idx.split( '.' );
- if ( events[ i ].idx == idx || ( eventType[ 0 ] && eventType[ 0 ] == idx.replace( '.', '' ) ) ) {
- var evt = document.createEvent('HTMLEvents');
- evt.initEvent( eventType[ 0 ], false, true );
- this.sound.dispatchEvent( evt );
- }
- }
- }
- return this;
- }
- this.fadeTo = function( to, duration, callback ) {
- if ( !supported ) return this;
- if ( duration instanceof Function ) {
- callback = duration;
- duration = buzz.defaults.duration;
- } else {
- duration = duration || buzz.defaults.duration;
- }
- var from = this.volume,
- delay = duration / Math.abs( from - to ),
- that = this;
- this.play();
- function doFade() {
- setTimeout( function() {
- if ( from < to && that.volume < to ) {
- that.setVolume( that.volume += 1 );
- doFade();
- } else if ( from > to && that.volume > to ) {
- that.setVolume( that.volume -= 1 );
- doFade();
- } else if ( callback instanceof Function ) {
- callback.apply( that );
- }
- }, delay );
- }
- this.whenReady( function() {
- doFade();
- });
- return this;
- }
- this.fadeIn = function( duration, callback ) {
- if ( !supported ) return this;
- return this.setVolume(0).fadeTo( 100, duration, callback );
- }
- this.fadeOut = function( duration, callback ) {
- if ( !supported ) return this;
- return this.fadeTo( 0, duration, callback );
- }
- this.fadeWith = function( sound, duration ) {
- if ( !supported ) return this;
- this.fadeOut( duration, function() {
- this.stop();
- });
- sound.play().fadeIn( duration );
- return this;
- }
- this.whenReady = function( func ) {
- if ( !supported ) return null;
- var that = this;
- if ( this.sound.readyState == 0 ) {
- this.bind( 'canplay.buzzwhenready', function() {
- func.call( that );
- });
- } else {
- func.call( that );
- }
- }
- // privates
- function timerangeToArray( timeRange ) {
- var array = [],
- length = timeRange.length - 1;
- for( var i = 0; i <= length; i++ ) {
- array.push({
- start: timeRange.start( length ),
- end: timeRange.end( length )
- });
- }
- return array;
- }
- function getExt( filename ) {
- return filename.split('.').pop();
- }
-
- function addSource( sound, src ) {
- var source = document.createElement( 'source' );
- source.src = src;
- if ( buzz.types[ getExt( src ) ] ) {
- source.type = buzz.types[ getExt( src ) ];
- }
- sound.appendChild( source );
- }
- // init
- if ( supported ) {
-
- for( i in buzz.defaults ) {
- options[ i ] = options[ i ] || buzz.defaults[ i ];
- }
- this.sound = document.createElement( 'audio' );
- if ( src instanceof Array ) {
- for( var i in src ) {
- addSource( this.sound, src[ i ] );
- }
- } else if ( options.formats.length ) {
- for( var i in options.formats ) {
- addSource( this.sound, src + '.' + options.formats[ i ] );
- }
- } else {
- addSource( this.sound, src );
- }
- if ( options.loop ) {
- this.loop();
- }
- if ( options.autoplay ) {
- this.sound.autoplay = 'autoplay';
- }
- if ( options.preload === true ) {
- this.sound.preload = 'auto';
- } else if ( options.preload === false ) {
- this.sound.preload = 'none';
- } else {
- this.sound.preload = options.preload;
- }
- this.setVolume( options.volume );
- buzz.sounds.push( this );
- }
- },
- group: function( sounds ) {
- var sounds = argsToArray( sounds, arguments );
- // publics
- this.getSounds = function() {
- return sounds;
- }
- this.add = function( soundArray ) {
- var soundArray = argsToArray( soundArray, arguments );
- for( var a = 0; a < soundArray.length; a++ ) {
- for( var i = 0; i < sounds.length; i++ ) {
- sounds.push( soundArray[ a ] );
- }
- }
- }
- this.remove = function( soundArray ) {
- var soundArray = argsToArray( soundArray, arguments );
- for( var a = 0; a < soundArray.length; a++ ) {
- for( var i = 0; i < sounds.length; i++ ) {
- if ( sounds[ i ] == soundArray[ a ] ) {
- delete sounds[ i ];
- break;
- }
- }
- }
- }
- this.load = function() {
- fn( 'load' );
- return this;
- }
- this.play = function() {
- fn( 'play' );
- return this;
- }
- this.togglePlay = function( ) {
- fn( 'togglePlay' );
- return this;
- }
- this.pause = function( time ) {
- fn( 'pause', time );
- return this;
- }
- this.stop = function() {
- fn( 'stop' );
- return this;
- }
- this.mute = function() {
- fn( 'mute' );
- return this;
- }
- this.unmute = function() {
- fn( 'unmute' );
- return this;
- }
- this.toggleMute = function() {
- fn( 'toggleMute' );
- return this;
- }
- this.setVolume = function( volume ) {
- fn( 'setVolume', volume );
- return this;
- }
- this.increaseVolume = function( value ) {
- fn( 'increaseVolume', value );
- return this;
- }
- this.decreaseVolume = function( value ) {
- fn( 'decreaseVolume', value );
- return this;
- }
- this.loop = function() {
- fn( 'loop' );
- return this;
- }
- this.unloop = function() {
- fn( 'unloop' );
- return this;
- }
- this.setTime = function( time ) {
- fn( 'setTime', time );
- return this;
- }
- this.setduration = function( duration ) {
- fn( 'setduration', duration );
- return this;
- }
- this.set = function( key, value ) {
- fn( 'set', key, value );
- return this;
- }
- this.bind = function( type, func ) {
- fn( 'bind', type, func );
- return this;
- }
- this.unbind = function( type ) {
- fn( 'unbind', type );
- return this;
- }
- this.bindOnce = function( type, func ) {
- fn( 'bindOnce', type, func );
- return this;
- }
- this.trigger = function( type ) {
- fn( 'trigger', type );
- return this;
- }
- this.fade = function( from, to, duration, callback ) {
- fn( 'fade', from, to, duration, callback );
- return this;
- }
- this.fadeIn = function( duration, callback ) {
- fn( 'fadeIn', duration, callback );
- return this;
- }
- this.fadeOut = function( duration, callback ) {
- fn( 'fadeOut', duration, callback );
- return this;
- }
- // privates
- function fn() {
- var args = argsToArray( null, arguments ),
- func = args.shift();
- for( var i = 0; i < sounds.length; i++ ) {
- sounds[ i ][ func ].apply( sounds[ i ], args );
- }
- }
- function argsToArray( array, args ) {
- return ( array instanceof Array ) ? array : Array.prototype.slice.call( args );
- }
- },
- all: function() {
- return new buzz.group( buzz.sounds );
- },
- isSupported: function() {
- return !!this.el.canPlayType;
- },
- isOGGSupported: function() {
- return !!this.el.canPlayType && this.el.canPlayType( 'audio/ogg; codecs="vorbis"' );
- },
- isWAVSupported: function() {
- return !!this.el.canPlayType && this.el.canPlayType( 'audio/wav; codecs="1"' );
- },
- isMP3Supported: function() {
- return !!this.el.canPlayType && this.el.canPlayType( 'audio/mpeg;' );
- },
- isAACSupported: function() {
- return !!this.el.canPlayType && ( this.el.canPlayType( 'audio/x-m4a;' ) || this.el.canPlayType( 'audio/aac;' ) );
- },
- toTimer: function( time, withHours ) {
- h = Math.floor( time / 3600 );
- h = isNaN( h ) ? '--' : ( h >= 10 ) ? h : '0' + h;
- m = withHours ? Math.floor( time / 60 % 60 ) : Math.floor( time / 60 );
- m = isNaN( m ) ? '--' : ( m >= 10 ) ? m : '0' + m;
- s = Math.floor( time % 60 );
- s = isNaN( s ) ? '--' : ( s >= 10 ) ? s : '0' + s;
- return withHours ? h + ':' + m + ':' + s : m + ':' + s;
- },
- fromTimer: function( time ) {
- var splits = time.toString().split( ':' );
- if ( splits && splits.length == 3 ) {
- time = ( parseInt( splits[ 0 ] ) * 3600 ) + ( parseInt(splits[ 1 ] ) * 60 ) + parseInt( splits[ 2 ] );
- }
- if ( splits && splits.length == 2 ) {
- time = ( parseInt( splits[ 0 ] ) * 60 ) + parseInt( splits[ 1 ] );
- }
- return time;
- },
- toPercent: function( value, total, decimal ) {
- var r = Math.pow( 10, decimal || 0 );
- return Math.round( ( ( value * 100 ) / total ) * r ) / r;
- },
- fromPercent: function( percent, total, decimal ) {
- var r = Math.pow( 10, decimal || 0 );
- return Math.round( ( ( total / 100 ) * percent ) * r ) / r;
- }
- }
|