NetStream, bytesTotal & GZip issues

Posted: 07/07/08

An image of NetStream, bytesTotal & GZip issues

Some recent server changes, and the release of Firefox 3 have helped expose some serious issues in the NetStream object, when using it for progressively downloaded FLV assets.

To save on bandwidth, server teams often switch-on GZip compression allowing browsers that support content in this format to request it. Files are compressed on the server and delivered to the client using less bandwidth than would otherwise be required. At the client, the compressed files are unpacked by the browser (behind the scenes) and viewed in the normal way.

When a FLV file is received in this format, it is unpacked in stages and passed through to the Flash Player instance, running inside the browser. The Flash Player should see the video meta-data in the first package, along with some of the first video data. This *should* be enough for the player to begin playback; however, the file-size is often unknown at this stage, particularly if the file is still downloading from the server. Usually, developers wait for the meta-data event, and then begin playback, however the file-size can often be misreported so early on in the download, and result in the NetStream object believing it has reached the end of the video. Assume a file of 3.5mb starts playing on the meta-data event; because of the progressive nature of the download, and the decompression tasks being undertaken by the browser, the file-size may initially only appear to be 35k. When this occurs, you'll get a NetStream.Play.Start NetStatusEvent code following immediately by a NetSteam.Play.Stop.

To get around this, you need to first of all ensure the video buffer fills. So creating a flag that is set to true when the NetStream.Buffer.Full NetStatusEvent occurs, and then checking for this whenever NetStream.Play.Stop is fired will prevent videos ending before they appear to have even started.

Secondary to this problem is the issue of bytesTotal and bytesLoaded. I have come to the opinion is that bytesTotal is far too unreliable to use these days, and instead prefer using the datasize property on the meta-data info object. For various reasons to do with the unpacking of GZipped content, the bytesTotal value often is the same as the bytesLoaded value, creeping up as more of the file downloads. That's rubbish and can't be relied upon! When you're trying to work out how much of your video has downloaded, you'll be far better off using

var percent:Number = ( bytesLoaded / datasize ) * 100;

So in conclusion, it seems that whilst there are some real troubles with the video APIs in Flash right now - I'm sure partly because little has changed with these libraries since Flash 7 - this one probably is an issue with the server configuration, and not the player runtime. You shouldn't need to be GZipping video content, as hardly any more compression will be achieved over and above what the encoder has managed. Consider turning it off (if you can) for certain mime-types; thereby reducing the work your server CPU has to do for each request, and removing the need to handle GZipped progressive downloads.

Update: 01/10/2008

If you're working with H.264 encoded videos (such as mp4 container files) you don't have the datasize property available to you, as it's only applicable to FLV container files. Under these circumstances, you're going to have to use bytesloaded and battle through any GZip compatability issues, or turn off GZip (better)!!

Keywords for this post: flash, actionscript3, netstream, bytesTotal, bytesloaded, gzip, firefox, buffer, video