audioplayer.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. AUTHOR: Osvaldas Valutis, www.osvaldas.info
  3. */
  4. ;(function( $, window, document, undefined )
  5. {
  6. var isTouch = 'ontouchstart' in window,
  7. eStart = isTouch ? 'touchstart' : 'mousedown',
  8. eMove = isTouch ? 'touchmove' : 'mousemove',
  9. eEnd = isTouch ? 'touchend' : 'mouseup',
  10. eCancel = isTouch ? 'touchcancel' : 'mouseup',
  11. secondsToTime = function( secs )
  12. {
  13. var hours = Math.floor( secs / 3600 ), minutes = Math.floor( secs % 3600 / 60 ), seconds = Math.ceil( secs % 3600 % 60 );
  14. 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 );
  15. },
  16. canPlayType = function( file )
  17. {
  18. var audioElement = document.createElement( 'audio' );
  19. return !!( audioElement.canPlayType && audioElement.canPlayType( 'audio/' + file.split( '.' ).pop().toLowerCase() + ';' ).replace( /no/, '' ) );
  20. };
  21. $.fn.audioPlayer = function( params )
  22. {
  23. var params = $.extend( { classPrefix: 'audioplayer', strPlay: 'Play', strPause: 'Pause', strVolume: 'Volume' }, params ),
  24. cssClass = {},
  25. cssClassSub =
  26. {
  27. playPause: 'playpause',
  28. playing: 'playing',
  29. time: 'time',
  30. timeCurrent: 'time-current',
  31. timeDuration: 'time-duration',
  32. bar: 'bar',
  33. barLoaded: 'bar-loaded',
  34. barPlayed: 'bar-played',
  35. volume: 'volume',
  36. volumeButton: 'volume-button',
  37. volumeAdjust: 'volume-adjust',
  38. noVolume: 'novolume',
  39. mute: 'mute',
  40. mini: 'mini'
  41. };
  42. for( var subName in cssClassSub )
  43. cssClass[ subName ] = params.classPrefix + '-' + cssClassSub[ subName ];
  44. this.each( function()
  45. {
  46. if( $( this ).prop( 'tagName' ).toLowerCase() != 'audio' )
  47. return false;
  48. var $this = $( this ),
  49. audioFile = $this.attr( 'src' ),
  50. isAutoPlay = $this.get( 0 ).getAttribute( 'autoplay' ), isAutoPlay = isAutoPlay === '' || isAutoPlay === 'autoplay' ? true : false,
  51. isLoop = $this.get( 0 ).getAttribute( 'loop' ), isLoop = isLoop === '' || isLoop === 'loop' ? true : false,
  52. isSupport = false;
  53. if( typeof audioFile === 'undefined' )
  54. {
  55. $this.find( 'source' ).each( function()
  56. {
  57. audioFile = $( this ).attr( 'src' );
  58. if( typeof audioFile !== 'undefined' && canPlayType( audioFile ) )
  59. {
  60. isSupport = true;
  61. return false;
  62. }
  63. });
  64. }
  65. else if( canPlayType( audioFile ) ) isSupport = true;
  66. var thePlayer = $( '<div class="' + params.classPrefix + '">' + ( isSupport ? $( '<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="javascript:void(0)">' + params.strPlay + '</a></div></div>' ),
  67. theAudio = isSupport ? thePlayer.find( 'audio' ) : thePlayer.find( 'embed' ), theAudio = theAudio.get( 0 );
  68. if( isSupport )
  69. {
  70. thePlayer.find( 'audio' ).css( { 'width': 0, 'height': 0, 'visibility': 'hidden' } );
  71. 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="javascript:void(0)">' + params.strVolume + '</a></div><div class="' + cssClass.volumeAdjust + '"><div><div></div></div></div></div>' );
  72. var theBar = thePlayer.find( '.' + cssClass.bar ),
  73. barPlayed = thePlayer.find( '.' + cssClass.barPlayed ),
  74. barLoaded = thePlayer.find( '.' + cssClass.barLoaded ),
  75. timeCurrent = thePlayer.find( '.' + cssClass.timeCurrent ),
  76. timeDuration = thePlayer.find( '.' + cssClass.timeDuration ),
  77. timeCurrent1 = $('.currenttime'),//hg add
  78. timeDuration2 = $('.durationtime'),//hg add
  79. volumeButton = thePlayer.find( '.' + cssClass.volumeButton ),
  80. volumeAdjuster = thePlayer.find( '.' + cssClass.volumeAdjust + ' > div' ),
  81. volumeDefault = 0,
  82. adjustCurrentTime = function( e )
  83. {
  84. theRealEvent = isTouch ? e.originalEvent.touches[ 0 ] : e;
  85. theAudio.currentTime = Math.round( ( theAudio.duration * ( theRealEvent.pageX - theBar.offset().left ) ) / theBar.width() );
  86. },
  87. adjustVolume = function( e )
  88. {
  89. theRealEvent = isTouch ? e.originalEvent.touches[ 0 ] : e;
  90. theAudio.volume = Math.abs( ( theRealEvent.pageY - ( volumeAdjuster.offset().top + volumeAdjuster.height() ) ) / volumeAdjuster.height() );
  91. },
  92. updateLoadBar = setInterval( function()
  93. {
  94. barLoaded.width( ( theAudio.buffered.end( 0 ) / theAudio.duration ) * 100 + '%' );
  95. if( theAudio.buffered.end( 0 ) >= theAudio.duration )
  96. clearInterval( updateLoadBar );
  97. }, 100 );
  98. var volumeTestDefault = theAudio.volume, volumeTestValue = theAudio.volume = 0.111;
  99. if( Math.round( theAudio.volume * 1000 ) / 1000 == volumeTestValue ) theAudio.volume = volumeTestDefault;
  100. else thePlayer.addClass( cssClass.noVolume );
  101. timeDuration.html( '&hellip;' );
  102. timeDuration2.html( '&hellip;' );//hg add
  103. timeCurrent.text( secondsToTime( 0 ) );
  104. timeCurrent1.text( secondsToTime( 0 ) );//hg add
  105. theAudio.addEventListener( 'loadeddata', function()
  106. {
  107. timeDuration.text( secondsToTime( theAudio.duration ) );
  108. timeDuration2.text( secondsToTime( theAudio.duration ) );//hg add
  109. volumeAdjuster.find( 'div' ).height( theAudio.volume * 100 + '%' );
  110. volumeDefault = theAudio.volume;
  111. });
  112. theAudio.addEventListener( 'timeupdate', function()
  113. {
  114. timeCurrent.text( secondsToTime( theAudio.currentTime ) );
  115. timeCurrent1.text( secondsToTime( theAudio.currentTime ) );
  116. barPlayed.width( ( theAudio.currentTime / theAudio.duration ) * 100 + '%' );
  117. });
  118. theAudio.addEventListener( 'volumechange', function()
  119. {
  120. volumeAdjuster.find( 'div' ).height( theAudio.volume * 100 + '%' );
  121. if( theAudio.volume > 0 && thePlayer.hasClass( cssClass.mute ) ) thePlayer.removeClass( cssClass.mute );
  122. if( theAudio.volume <= 0 && !thePlayer.hasClass( cssClass.mute ) ) thePlayer.addClass( cssClass.mute );
  123. });
  124. theAudio.addEventListener( 'ended', function()
  125. {
  126. thePlayer.removeClass( cssClass.playing );
  127. });
  128. theBar.on( eStart, function( e )
  129. {
  130. adjustCurrentTime( e );
  131. theBar.on( eMove, function( e ) { adjustCurrentTime( e ); } );
  132. })
  133. .on( eCancel, function()
  134. {
  135. theBar.unbind( eMove );
  136. });
  137. volumeButton.on( 'click', function()
  138. {
  139. if( thePlayer.hasClass( cssClass.mute ) )
  140. {
  141. thePlayer.removeClass( cssClass.mute );
  142. theAudio.volume = volumeDefault;
  143. }
  144. else
  145. {
  146. thePlayer.addClass( cssClass.mute );
  147. volumeDefault = theAudio.volume;
  148. theAudio.volume = 0;
  149. }
  150. return false;
  151. });
  152. volumeAdjuster.on( eStart, function( e )
  153. {
  154. adjustVolume( e );
  155. volumeAdjuster.on( eMove, function( e ) { adjustVolume( e ); } );
  156. })
  157. .on( eCancel, function()
  158. {
  159. volumeAdjuster.unbind( eMove );
  160. });
  161. }
  162. else thePlayer.addClass( cssClass.mini );
  163. if( isAutoPlay ) thePlayer.addClass( cssClass.playing );
  164. thePlayer.find( '.' + cssClass.playPause ).on( 'click', function()
  165. {
  166. if( thePlayer.hasClass( cssClass.playing ) )
  167. {
  168. $( this ).attr( 'title', params.strPlay ).find( 'a' ).html( params.strPlay );
  169. thePlayer.removeClass( cssClass.playing );
  170. isSupport ? theAudio.pause() : theAudio.Stop();
  171. }
  172. else
  173. {
  174. $( this ).attr( 'title', params.strPause ).find( 'a' ).html( params.strPause );
  175. thePlayer.addClass( cssClass.playing );
  176. isSupport ? theAudio.play() : theAudio.Play();
  177. }
  178. return false;
  179. });
  180. $this.replaceWith( thePlayer );
  181. });
  182. return this;
  183. };
  184. })( jQuery, window, document );