0

I've tentatively started converting some musician sites from SWFObject flash player to HTML5... more for the ease of styling it offers than anything else. Frankly, SWFObject and Flash have always worked efficiently/reliably for me. And having to load 3 versions of each audio clip (for x-browser compatibility) is a drag.

The HTML5 audio -seems- to work OK for 1 file, but I added a very simple random 'player' with a progress bar for a dozen files and it seems like it's really slowing the site down. Sometimes the page hangs. Sometimes there is a 'waiting' status msg in FireFox---although the page appears to work OK.

I guess my immediate questions are: 1) is there an easy way to monitor the specific 'traffic' the audio tag is requesting from the server--to pinpoint the bottleneck, either in my code or in the tag itself?

2) Is this performance issue a known problem with HTML5? IOW: should I stick with Flash for now because it's still intrinsically more efficient?

3) And of course, is there some code problem sticking out like a sore thumb that I don't see being a novice at this?

The page is: http://jchmusic.com/detroit-the-opera/

Below is my rudimentary audio player code... php then jQuery.

TIA,

---JC

function jchAudioPlayer() {
  $path = '/var/chroot/home/content/html/downloads/snippets' ;
$str = '';
if ($handle = opendir( $path ) ) {

    $num=0;
    $a = array();
  while (false !== ($entry = readdir($handle))) {
   if ($entry != "." && $entry != "..")
         $path_parts = pathinfo( $entry);
         if( $path_parts['extension'] == 'mp3')
             $a[] = $entry;              
    }

    shuffle($a);

    $path_parts = pathinfo( $a[0] );
    $openingfile = $path_parts['filename'];
    $str .=  '<div class="autoplay audioplayer-wrapper" rel="/downloads/snippets/detroit/' . $openingfile . '">';
    $str .=  '<div class="audio-controls"><div class="progress-wrapper"><span class="progress"></span></div><a class="play5 pause" href="#"></a></div>';        
    $str .= '<div class="audioplayer">';

    foreach($a as $entry) {
 $path_parts = pathinfo( $entry);
     $basefile = $path_parts['filename'];
   $num++;
     $rn = rand(6,36);
   $str .= '<div class="songpara"><a style="font-size: ' . $rn . 'px" rel="' . $num . '" class="play5' . ( ($basefile == $openingfile) ? ' playing' : '') . '" href="/downloads/snippets/' . $basefile . '">' . $basefile . '</a></div>' ;

     }

$str .=  '</div>';        
$str .=  '</div>';

 closedir($handle);
 }  
return $str;
   }

   ?>


jQuery( init );

// Initialize the form
function init() {

//audio
var audioTagSupport = !!(document.createElement('audio').canPlayType);

if( audioTagSupport ) {
    var myAudio= new Audio(""); 
    // Need to check the canPlayType first or an exception will be thrown for those browsers that don't support it
    if (myAudio.canPlayType) {
       // Currently canPlayType(type) returns: "no", "maybe" or "probably"
        canPlayOgg = ("no" != myAudio.canPlayType("audio/ogg")) && ("" != myAudio.canPlayType("audio/ogg"));
        canPlayMp3 = ("no" != myAudio.canPlayType("audio/mpeg")) && ("" != myAudio.canPlayType("audio/mpeg"));
        canPlayWav = ("no" != myAudio.canPlayType("audio/wav")) && ("" != myAudio.canPlayType("audio/wav"));

    var ext;
    if(canPlayOgg)
      ext = '.ogg';
    else if(canPlayMp3)
      ext = '.mp3';
    else if(canPlayWav)
      ext = '.wav';
    }

  // ext = '.mp3';
  // alert( ext );

  jQuery('.play5').addClass('paused');      

  if( ext && audioTagSupport ) {         
      var audioElements = [];
      jQuery('.play5').each( function(i) {
            var y = 0;
            var x;
            var xv = jQuery(this);
            x = jQuery(this).attr('href') + ext;                                                
            audioElements.push( document.createElement('audio') ); 
            y = audioElements.length-1;
            audioElements[y].setAttribute('src', x);
            audioElements[y].load();
            audioElements[y].addEventListener("canplay", function(){ xv.addClass('canplay');    }); 
            audioElements[y].addEventListener("timeupdate", function() {
                                            var value = 0; 
                                            var aLink = this;
                                            if ( aLink.currentTime > 0) 
                                             { value = Math.floor( (100 / aLink.duration) * aLink.currentTime); } 
                                            jQuery('.progress').css('width', value + "%")}, false);
            //   audioElements[y].currentTime=0;                         
        });

        function updateProgress( aLink ) { 
            var value = 0; 
            if ( aLink.currentTime > 0) 
             { value = Math.floor( (100 / aLink.duration) * aLink.currentTime); } 
            jQuery('.progress').css('width', value + "%");
        }

        // add a 'self play' function. usually put on wrapper div
        jQuery('.autoplay').each( function(i) {
            if( jQuery(this).attr("rel") ) {   
                var xv = jQuery(this);
                var y = 0;
                var x;
                x = jQuery(this).attr('rel') + ext;                                             
                audioElements.push( document.createElement('audio') ); 
                //alert(audioElements.length);
                //alert(xv);
                // alert(x);
                y = audioElements.length-1;
                audioElements[y].setAttribute('src', x);
                audioElements[y].load();
                audioElements[y].addEventListener("canplay", function(){ xv.addClass('canplay');    });             
                audioElements[y].play();
                // alert(x);
                // return true;
            }
        });

        // stop playback on click through (note returns true so default carries on)
        jQuery('.autoplay a').click( function(e) {
            var playMsg = 'Play';                                                                       
            var pauseMsg = 'Pause';                                                                                     
            var y = audioElements.length-1;
            if( jQuery(this).hasClass('playpause') ) {                                                                                      
            e.preventDefault();                                 
                if( jQuery(this).hasClass('paused') ) {
                    audioElements[y].play();                        
                    jQuery(this).text(pauseMsg)
                    jQuery(this).removeClass('paused')
                }else{ 
                    audioElements[y].pause();   
                    jQuery(this).text(playMsg)                      
                    jQuery(this).addClass('paused')
                }
            }   else {
                audioElements[y].pause();
                return true;                
            }
         });

        //audio player


        jQuery('.play5').click(function(e) {
            e.preventDefault();                                                     
            if( jQuery(this).hasClass('pause') ) {
            for( var p = 0; p < audioElements.length;) 
                { audioElements[p].pause(); 
                    //audioElements[p].currentTime=0;                        
                  p++; };
                jQuery('.play5.playing').removeClass('playing').addClass('paused');                                                          

            } else if( jQuery(this).hasClass('paused') && jQuery(this).hasClass('canplay') ) {
                jQuery('.play5').each( function(i) {
                    var x = jQuery(this);                                               
                    jQuery(x).removeClass('playing');
                    jQuery(x).addClass('paused');       
                    var z = jQuery(x).attr('rel');       
                    audioElements[z].pause();
                });
                for( var p = 0; p < audioElements.length;) { audioElements[p].pause(); p++; };
                    jQuery(this).removeClass('paused');                                                          
                    jQuery(this).addClass('playing');                                                       
                    var z = jQuery(this).attr('rel');
                    audioElements[z].currentTime=0;                      
                    audioElements[z].play();

            } else {
                jQuery('#title').removeClass('playing');         
                jQuery(this).removeClass('playing');                                                                     
                jQuery(this).addClass('paused');        
                var z = jQuery(this).attr('rel');        
                audioElements[z].pause();
            }

        });

  }

} // audioTagSupport

}
jchwebdev
  • 5,034
  • 5
  • 21
  • 30
  • Flash is not intrinsically efficient. Use your browser's development tools to figure out what is going on. – Brad Nov 26 '12 at 18:35
  • Sorry if this seems so 'noob': Can you (or someone) give me a hint on how to monitor 'traffic'... ie. Ideally, I'd like some sort of running list of not just http requests, but some easy way to identify which jQuery or js is firing and which is taking up the most cycles. I mainly use Firefox. TIA ---JC – jchwebdev Nov 28 '12 at 20:37
  • Chrome's developer tools are top notch, and the go-to tool for this, in my opinion. Check this out: https://developers.google.com/chrome-developer-tools/docs/profiles The network tab will help you with network requests, but Chrome's tools will allow you to check CPU and memory usage. There's something like this for Firefox, isn't there? I don't know for certain, as I use Chrome primarily. – Brad Nov 28 '12 at 21:11
  • Thanks. I'll read that. Primarily, here's what I'd like to know... Is there a way to easily see a 'trace' of which JS listeners are 'firing' on a particular element? IOW: what I'm beginning to notice is that, if one has say 10 plug-ins, all 10 may be 'firing' on a particular click or page load... even though only 2 are necessary for that particular element or page. I want to figure out how to know which plugs are superfluous on a page or are interfering with one another. I think my slowness is because certain JS is firing over and over and I want some methodical way to better isolate. Thx. – jchwebdev Nov 29 '12 at 18:29
  • Set a breakpoint on a particular function that you want to monitor, and view the backtrace. If you want to do this for a lot of functions, or want a nice log, you can always `console.log(arguments.callee.caller.name)`, or use something like this: http://snipplr.com/view/23047/javascript-backtrace-function/ See also: http://stackoverflow.com/q/280389/362536 – Brad Nov 29 '12 at 19:59

0 Answers0