Adaptive preloader / Buffering SWFs

I might be going back a few years here, but I need help with a solid and efficient adaptive preloader. A previous thread concerns the same issue, only for FLV: http://www.actionscript.org/forums/showthread.php3?t=105158 … and this builds on an old tutorial from Wildform found here: http://www.wildform.com/tutorials/adaptive_preloader/

The version I’m working on also builds on Wildform’s example, but I’ve tried to fix a few things:

  • Optimizing for high bandwidth (starts without preloading)
  • Seeks to find “new available loading time” for users in between narrow and broadband (hard to explain, look for the “availableLoadTime” var.
  • Avoids using getTimer() in case reusing code for several SWFs.
  • Uses onEnterFrame instead of looping between frames as done in Wildform’s tutorial

I’d appreciate any input and suggestions to new principles or whatever. Great if you have a look at the code below. Download files below, and find a sample movie here www.ewf.no/download/movie_small.zip

Please disregard all the added vars in the code.

Thanks.

PS - I’ve also posted this thread on actionscript.org as I really am in need of the best solution. Will post final solution on both threads.

this.createEmptyMovieClip("contentContainer", this.getNextHighestDepth());
  contentContainer.createEmptyMovieClip("swfMovie", this.getNextHighestDepth());
   
  //specify your own movie or download from www.ewf.no/download/movie_small.zip
  //movie will be available for a few weeks
  var swfUrl:String = "movie_small.swf";
  var swfTarget:MovieClip = contentContainer.swfMovie;
   
  swfTarget.loadMovie(swfUrl);
  swfTarget._x = -350;
  preloadAdaptSWF(swfTarget);
   
  function preloadAdaptSWF(targetMc) {
              eval(targetMc).stop();
              swfPlaying = false;
              doneLoading = false;
              subtractingTime = false;
              count = 0;
              this.onEnterFrame = function() {
                          fps = 25;
                          bufferFactor = 1.2;
                          count++;
                          //
                          totalBytes = eval(targetMc).getBytesTotal();
                          loadedBytes = eval(targetMc).getBytesLoaded();
                          leftBytes = totalBytes-loadedBytes;
                          loadedPercBytes = Math.round((loadedBytes/totalBytes)*100);
                          //
                          totalFrames = eval(targetMc)._totalframes;
                          loadedFrames = eval(targetMc)._framesloaded;
                          currentFrame = eval(targetMc)._currentframe;
                          frameDiff = loadedFrames-currentFrame;
                          //
                          totalSwfTime = totalFrames/fps;             
                          currentSwfTime = currentFrame/fps;
                          timeSpentLoading = count/fps;
                          //
                          speed = (loadedBytes/timeSpentLoading)/1024;
                          //
                          totalLoadTime = (totalBytes/1024)/speed;
                          loadTimePerc = Math.round((leftLoadTime/totalLoadTime)*100);               
                          playTimeLoaded = loadedFrames/fps;
                          playTimeLoadedPerc = Math.round((playTimeLoaded/totalSwfTime)*100);
                          //
                          
                          availableLoadTime = totalSwfTime-(totalLoadTime-totalSwfTime);             
                          if (availableLoadTime>0 && availableLoadTime<totalSwfTime) {
                                     leftLoadTime = ((leftBytes/1024)/speed)-availableLoadTime;
                                     subtractingTime = true;
                          } else {
                                     leftLoadTime = ((leftBytes/1024)/speed);
                                     subtractingTime = false;
                          }
                          
                          //Allow 1 sec calculation
                          if (loadedFrames>fps) {
                                     
                                     //Start if no preloading needed
                                     if (totalSwfTime>totalLoadTime*bufferFactor) {
                                                 eval(targetMc).play();
                                                 info = "Playing without preload";
                                                 swfPlaying = true;
                                     
                                     //Provide info if preloading is needed
                                     } else if (playTimeLoaded<=(leftLoadTime*bufferFactor) && swfPlaying == false) {
                                                 info = "Buffering in loop";
                                                 playedAtFrame = loadedFrames;
                                                 playedAtPerc = loadedPercBytes;
                                     
                                     //Start when preloaded
                                     } else if (playTimeLoaded>=(leftLoadTime*bufferFactor) && swfPlaying == false) {                         
                                                 eval(targetMc).play();
                                                 info = "Playing after preload";
                                                 swfPlaying = true;                                             
                                     
                                     //All loaded
                                     } else if (loadedBytes>=totalBytes && doneLoading == false) {
                                                 info = "Done loading...";
                                                 doneLoading = true;
                                                 frameDiffAtLoaded = currentFrame;
                                     
                                     //All played
                                     } else if (currentFrame>=totalFrames && doneLoading == true) {
                                                 info = "Finished playing...";
                                                 eval(targetMc).stop();
                                                 delete this.onEnterFrame;
                                     }
                                     
                          //Allow 1 sec for calculation
                          } else {
                                     eval(targetMc).stop();
                                     info = "Buffering 1 sec";
                          }
              };
  }
  stop();

[FONT=Arial] [/FONT]