1;(function( $, window, document, undefined ) 2{ 3 var isTouch = 'ontouchstart' in window, 4 eStart = isTouch ? 'touchstart' : 'mousedown', 5 eMove = isTouch ? 'touchmove' : 'mousemove', 6 eEnd = isTouch ? 'touchend' : 'mouseup', 7 eCancel = isTouch ? 'touchcancel' : 'mouseup', 8 secondsToTime = function( secs ) 9 { 10 var hours = Math.floor( secs / 3600 ), minutes = Math.floor( secs % 3600 / 60 ), seconds = Math.ceil( secs % 3600 % 60 ); 11 return ( hours == 0 ? '' : hours > 0 && hours.toString().length < 2 ? '0'+hours+':' : hours+':' ) + ( minutes.toString().length < 2 ? '0'+minutes : minutes ) + ':' + ( seconds.toString().length < 2 ? '0'+seconds : seconds ); 12 }, 13 canPlayType = function( file ) 14 { 15 var audioElement = document.createElement( 'audio' ); 16 return !!( audioElement.canPlayType && audioElement.canPlayType( 'audio/' + file.split( '.' ).pop().toLowerCase() + ';' ).replace( /no/, '' ) ); 17 }; 18 19 $.fn.audioPlayer = function( params ) 20 { 21 var params = $.extend( { classPrefix: 'audioplayer', strPlay: 'Play', strPause: 'Pause', strVolume: 'Volume',strControls:'',strStyle:'' }, params ), 22 cssClass = {}, 23 cssClassSub = 24 { 25 playPause: 'playpause', 26 playing: 'playing', 27 time: 'time', 28 timeCurrent: 'time-current', 29 timeDuration: 'time-duration', 30 bar: 'bar', 31 barLoaded: 'bar-loaded', 32 barPlayed: 'bar-played', 33 volume: 'volume', 34 volumeButton: 'volume-button', 35 volumeAdjust: 'volume-adjust', 36 noVolume: 'novolume', 37 mute: 'mute', 38 mini: 'mini' 39 }; 40 41 for( var subName in cssClassSub ) 42 cssClass[ subName ] = params.classPrefix + '-' + cssClassSub[ subName ]; 43 44 this.each( function() 45 { 46 if( $( this ).prop( 'tagName' ).toLowerCase() != 'audio' ) 47 return false; 48 49 var $this = $( this ), 50 audioFile = $this.attr( 'src' ), 51 isAutoPlay = $this.get( 0 ).getAttribute( 'data-autoplay' ), isAutoPlay = isAutoPlay === 'autoplay' ? true : false, 52 isLoop = $this.get( 0 ).getAttribute( 'data-loop' ), isLoop = isLoop === 'loop' ? true : false, 53 isMute = $this.get( 0 ).getAttribute( 'data-mute' ), isMute = isMute === 'mute' ? true : false, 54 55 isSupport = false; 56 57 if( typeof audioFile === 'undefined' ) 58 { 59 $this.find( 'source' ).each( function() 60 { 61 audioFile = $( this ).attr( 'src' ); 62 if( typeof audioFile !== 'undefined' && canPlayType( audioFile ) ) 63 { 64 isSupport = true; 65 return false; 66 } 67 }); 68 } 69 else if( canPlayType( audioFile ) ) isSupport = true; 70 71 var thePlayer = $( '<div class="' + params.classPrefix +' '+ params.strControls +' '+ params.strStyle +'">' + ( isSupport ? $( '<div></div>' ).append( $this.eq( 0 ).clone() ).html() : '<embed src="' + audioFile + '" width="0" height="0" volume="100" autostart="' + isAutoPlay.toString() +'" loop="' + isLoop.toString() + '" />' ) + '<div class="' + cssClass.playPause + '" title="' + params.strPlay + '"><a href="#">' + params.strPlay + '</a></div></div>' ), 72 theAudio = isSupport ? thePlayer.find( 'audio' ) : thePlayer.find( 'embed' ), theAudio = theAudio.get( 0 ); 73 74 if( isSupport ) 75 { 76 thePlayer.find( 'audio' ).css( { 'width': 0, 'height': 0, 'visibility': 'hidden' } ); 77 thePlayer.append( '<div class="' + cssClass.time + ' ' + cssClass.timeCurrent + '"></div><div class="' + cssClass.bar + '"><div class="' + cssClass.barLoaded + '"></div><div class="' + cssClass.barPlayed + '"></div></div><div class="' + cssClass.time + ' ' + cssClass.timeDuration + '"></div><div class="' + cssClass.volume + '"><div class="' + cssClass.volumeButton + '" title="' + params.strVolume + '"><a href="#">' + params.strVolume + '</a></div><div class="' + cssClass.volumeAdjust + '"><div><div></div></div></div></div>' ); 78 79 var theBar = thePlayer.find( '.' + cssClass.bar ), 80 barPlayed = thePlayer.find( '.' + cssClass.barPlayed ), 81 barLoaded = thePlayer.find( '.' + cssClass.barLoaded ), 82 timeCurrent = thePlayer.find( '.' + cssClass.timeCurrent ), 83 timeDuration = thePlayer.find( '.' + cssClass.timeDuration ), 84 volumeButton = thePlayer.find( '.' + cssClass.volumeButton ), 85 volumeAdjuster = thePlayer.find( '.' + cssClass.volumeAdjust + ' > div' ), 86 volumeDefault = 0, 87 adjustCurrentTime = function( e ) 88 { 89 theRealEvent = isTouch ? e.originalEvent.touches[ 0 ] : e; 90 theAudio.currentTime = Math.round( ( theAudio.duration * ( theRealEvent.pageX - theBar.offset().left ) ) / theBar.width() ); 91 }, 92 adjustVolume = function( e ) 93 { 94 theRealEvent = isTouch ? e.originalEvent.touches[ 0 ] : e; 95 theAudio.volume = 1 - Math.abs( ( ( volumeAdjuster.offset().left + volumeAdjuster.width())
95- theRealEvent.pageX ) / volumeAdjuster.width() ); 96 97 }, 98 updateLoadBar = setInterval( function() 99 { 100 //to fix the javascript bug INDEX_SIZE_ERR. 101 if(theAudio.buffered.length > 0){ 102 if(theAudio.duration > 0){ 103 barLoaded.width( ( theAudio.buffered.end( 0 ) / theAudio.duration ) * 100 + '%' ); 104 } 105 if( theAudio.buffered.end( 0 ) >= theAudio.duration ){ 106 clearInterval( updateLoadBar ); 107 } 108 } 109 }, 100 ); 110 111 var volumeTestDefault = theAudio.volume, volumeTestValue = theAudio.volume = 0.111; 112 if( Math.round( theAudio.volume * 1000 ) / 1000 == volumeTestValue ) theAudio.volume = volumeTestDefault; 113 else thePlayer.addClass( cssClass.noVolume ); 114 115 timeDuration.html( '…' ); 116 timeCurrent.text( secondsToTime( 0 ) ); 117 118 theAudio.addEventListener( 'loadeddata', function() 119 { 120 timeDuration.text( secondsToTime( theAudio.duration ) ); 121 volumeAdjuster.find( 'div' ).width( theAudio.volume * 100 + '%' ); 122 volumeDefault = theAudio.volume; 123 if( isAutoPlay ) {isSupport ? theAudio.play() : theAudio.Play();thePlayer.addClass( cssClass.playing );} 124 if(isMute){ 125 thePlayer.addClass( cssClass.mute ); 126 volumeDefault = theAudio.volume; 127 theAudio.volume = 0; 128 volumeAdjuster.find( 'div' ).width( theAudio.volume * 100 + '%' ); 129 } 130 }); 131 132 theAudio.addEventListener( 'timeupdate', function() 133 { 134 timeCurrent.text( secondsToTime( theAudio.currentTime ) ); 135 barPlayed.width( ( theAudio.currentTime / theAudio.duration ) * 100 + '%' ); 136 }); 137 138 theAudio.addEventListener( 'volumechange', function() 139 { 140 volumeAdjuster.find( 'div' ).width( theAudio.volume * 100 + '%' ); 141 if( theAudio.volume > 0 && thePlayer.hasClass( cssClass.mute ) ) thePlayer.removeClass( cssClass.mute ); 142 if( theAudio.volume <= 0 && !thePlayer.hasClass( cssClass.mute ) ) thePlayer.addClass( cssClass.mute ); 143 }); 144 145 theAudio.addEventListener( 'ended', function() 146 { 147 thePlayer.removeClass( cssClass.playing ); 148 if( isLoop ) { 149 isSupport ? theAudio.play() : theAudio.Play(); 150 thePlayer.addClass( cssClass.playing ); 151 } 152 153 }); 154 155 theBar.on( eStart, function( e ) 156 { 157 adjustCurrentTime( e ); 158 theBar.on( eMove, function( e ) { adjustCurrentTime( e ); } ); 159 }) 160 .on( eCancel, function() 161 { 162 theBar.unbind( eMove ); 163 }); 164 165 volumeButton.on( 'click', function() 166 { 167 if( thePlayer.hasClass( cssClass.mute ) ) 168 { 169 thePlayer.removeClass( cssClass.mute ); 170 theAudio.volume = volumeDefault; 171 } 172 else 173 { 174 thePlayer.addClass( cssClass.mute ); 175 volumeDefault = theAudio.volume; 176 theAudio.volume = 0; 177 } 178 return false; 179 }); 180 181 volumeAdjuster.on( eStart, function( e ) 182 { 183 adjustVolume( e ); 184 volumeAdjuster.on( eMove, function( e ) { adjustVolume( e ); } ); 185 }) 186 .on( eCancel, function() 187 { 188 volumeAdjuster.unbind( eMove ); 189 }); 190 } 191 else thePlayer.addClass( cssClass.mini ); 192 193 194 195 thePlayer.find( '.' + cssClass.playPause ).on( 'click', function() 196 { 197 if( thePlayer.hasClass( cssClass.playing ) ) 198 { 199 $( this ).attr( 'title', params.strPlay ).find( 'a' ).html( params.strPlay ); 200 thePlayer.removeClass( cssClass.playing ); 201 isSupport ? theAudio.pause() : theAudio.Stop(); 202 } 203 else 204 { 205 $( this ).attr( 'title', params.strPause ).find( 'a' ).html( params.strPause ); 206 thePlayer.addClass( cssClass.playing ); 207 isSupport ? theAudio.play() : theAudio.Play(); 208 } 209 return false; 210 }); 211 212 $this.replaceWith( thePlayer ); 213 }); 214 return this; 215 }; 216})( jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.