Preload flash .flv files into browser cache

Adobe Flash PositioningFound a great way to preload and cache flash .flv video files. Recently (2006) I was hired as the lead web-designer for an insurance company website with over 30 online videos to be placed throughout the site. My area of expertise when it comes to Web Development is web-standards, and pretty much anything else open-source, NOT flash. I started programming Flash back when it first came out, version 1.x, (and I think it was called something else..) because I was learning it for my job at the ISP.. The main reason I don't spend my time learning it (although actionscript is very very rad) is because I'm not a designer. I don't have the patience for colors and images and effects, that's boring to me, especially because I'm not gifted in the art department.

Preloading Cache

My employer is a video production firm, so I use flash (for video and small Advertisements and logos) on pretty much every site I work on, now... this article shows what I learned while building the insurance site and the solutions we came up with for it.

Note: This site had only 50-100 site visitors/day and each visitor typically viewed 3-10 of the videos, so this type of aggressive caching and bandwidth-raising techniques should be looked at on a site-by-site basis.


After using the site for a month I noticed that 8 of the 30 videos on the site were being using by almost every site visitor. To speed up the site I created a very small swf (flash 7) file that uses very minimal actionscript to preload flvs specified in a preloadlist.xml file

Any page that I want the flv files to be preloaded I have to have an element with an id of "preloading" or the javascript does not load the swf file. So I set it up so that the preloading only happens when visitors goto the homepage (where they typically land), and also only when visitors haven't already preloaded the flvs. To check for this I set a cookie when the flvs are preloaded.

Note there is a newer/briefer update to this technique.


CSS for preloading

If you give an element a display:none css attribute, it doesn't work for everyone. Once the swf loads you can of course change it to none as the preloader initiates the requests onload.

#preloading {position:absolute; bottom:0;left:0; display:block; width:1px; height:1px; overflow:hidden; z-index:1;}

XHTML for preloading

This just starts the preloadflv function AFTER the HTML file has been loaded... (nowadays I ONLY do unobtrusive javascript and keep everything in an external .js) Also note that some browsers/flash versions need the preloading span element to be at the top of the html if your html page scrolls down past the window's viewable area.

<body onload="preloadflv();">
<span id="preloading"></span>

Actionscript for preloadflv.fla

This is literally the whole file, I spent weeks researching to come up with this optimized and customized swf prefloader. One useful feature is by using the external .xml file you can preload any files dynamically. Just make sure you setup the caching correctly, don't cache the xml file for very long! To really appreciate this preloader you should definately use an HTTP capture program like WireShark and also watch your Apache access logs on your server.

var netPath:NetConnection = new NetConnection();
netPath.connect(null);
var ncPreLD:NetStream = new NetStream(netPath);
var i:Number = 1;
var preloaderXML:XML = new XML();
preloaderXML.ignoreWhite = true;
preloaderXML.onLoad = function(success:Boolean):Void  {
  if (success) {
    var flvFiles:Array = preloaderXML.firstChild.childNodes;
    var flvDir:String = preloaderXML.firstChild.attributes.basedir;
    ncPreLD.play(flvDir+preloaderXML.firstChild.childNodes[0].attributes.path+".flv");
    ncPreLD.onStatus = function(infoObject:Object):Void  {
      if (infoObject.code == "NetStream.Play.Start") {
        ncPreLD.pause();
        if (i<flvFiles.length) {
          ncPreLD.play(flvDir+preloaderXML.firstChild.childNodes[i].attributes.path+".flv");
          i++;
        }
      }
    };
  }
};
preloaderXML.load("preloadlist.xml");

XML file preloadlist.xml

Save this file in the directory of your preloader (unless you modify the .fla) and basically just list all the files to preload from the basedir url.

<?xml version="1.0" encoding="UTF-8"?>
<preloader basedir="http://s.askapache.net/f/flv/">
  <flv path="404-error-page.flv
  <flv path="404-google-plugin.flv
  <flv path="anonymous.flv
  <flv path="create-boot-ini.flv
  <flv path="install-recovery-console.flv
  <flv path="mysql-backup-script.flv
  <flv path="php-ajax-shell.flv
  <flv path="setup-recovery-console.flv
</preloader>

NetStream

The NetStream.onStatus

NetStream.Buffer.Empty
statusData is not being received quickly enough to fill the buffer. Data flow will be interrupted until the buffer refills, at which time a NetStream.Buffer.Full message will be sent and the stream will begin playing again.
NetStream.Buffer.Full
status The buffer is full and the stream will begin playing.
NetStream.Buffer.Flush
status Data has finished streaming, and the remaining buffer will be emptied.
NetStream.Play.Start
status Playback has started.
NetStream.Play.Stop
status Playback has stopped.
NetStream.Play.StreamNotFound
error The FLV passed to the play() method can't be found.
NetStream.Seek.InvalidTime
error For video downloaded with progressive download, the user has tried to seek or play past the end of the video data that has downloaded thus far, or past the end of the video once the entire file has downloaded. The message.details property contains a time code that indicates the last valid position to which the user can seek.
NetStream.Seek.Notify
status The seek operation is complete.

.htaccess flash and flv

Make sure apache sends the correct content-type headers with the swf and flv files

AddType video/x-flv .flv
AddType application/x-shockwave-flash .swf

Implement HTTP Caching

Please see: .htaccess Caching Tutorial

# 1 YEAR
<FilesMatch "\.(ico|pdf|flv)$">
Header set Expires "Mon, 27 Mar 2038 20:59:12 GMT"
Header set Cache-Control "max-age=29030400"
</FilesMatch>
# 1 WEEK
<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
# 3 HOUR
<FilesMatch "\.(css|xml|txt|js|html)$">
Header set Cache-Control "max-age=10800,must-revalidate"
</FilesMatch>

Optimization Actionscript Cache Caching Flash flv Htaccess preload SWF

Comments