Nasty FLV preloading issue

Came across a nasty bug with NetConnection and NetStream. 3 full hours wasted.. damn...

Flash is, by far, the best way to deliver video on the web. The wide availability of the plugin makes it a no brainer.

I always used progressive download video, meaning video that's read from a vanilla http connection, no special streaming server on the backend. I'd love to hear the stats, but my guess is that the majority of flash video is delivered this way. The huge video sites, youtube, google video and yahoo videos all use flash with progressive download. But the API for showing video content is highly skewed towards using Flash Media Server. Sure Adobe(then macromedia) expects to make a buck on that, but still it's pretty odd that the most common use case is so cumbersome to code.

With the great architectural changes I was really chocked to learn the the NetStream remained mostly unchanged. It's awkward to use. It's full of small confusing details and the documentation could be so much better. I sure am not the only one to feel this way. Traces from the youtube player, from the nytimes player make that clear.

So we hacked a sane VideoStream class for AS2 and I wanted to port it to AS3. The idea was to have a class that could do something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var vs : VideoStream = new VideoStream(url, buffertime);
// video loops once the end of the stream is reached
vs.loops = true ; 
// listen to complete loading events
vs.addEventListener(Event.COMPLETE, onVideoLoaded); 
// listen to loading progres events
vs.addEventListener(Event.PROGRESS, onLoadingProgress);
vs.addEventListener("playComplete", onPlayFinished);
  
// and then later:
// the video duration:
trace(vs.duration)
// and so on
In order to start a NetStream, you must instantiate it with a NetConnection object. it's ugly. You have to say:
1
2
3
nc = new NetConnection();
nc.connect(null);
stream = new NetStream(nc);

Why on earth you can't say simply stream = new NetStream(); and, with no parameters for the NetConnection, it would do it for you? Since the NetConnection object doesn't do anything, I coded this class differently. Instead of keeping the NetConnection as a class property, I simply created a local variable and used that to instantiate the NetStream. But then something funny would happen. For a while the NetStream.bytesLoaded and NetStream.bytesTotal would behave as expected, at first it would be zero, until the the response would return the content length and then it would show the right bytes total and bytes loaded for a few executions, and THEN it would read 0 for both. That's right, after a few milliseconds the bytesTotal would go from 28428 to 0. That combined with a miss configured apache omitting the content length, and it took us hours to chase this bug. Worse it wasn't very predictable: sometimes loading information would read correctly all the way trough.

Googling around, I came across this thread. The post is 3 years old, for flash MX , but it's the same issue. They found the workaround but didn't understand why. Here's what I think happens. When you create a new NetConnection and the NetStream object everything is fine. But if the NetConnection is a local variable inside a function it will be marked for garbage collection by the VM. At some point the gc kicks in and clears the NetConnection object, since it is a local variable. When that happens, the NetStream goes cuckoo and reads dummy values for bytesLoaded. Because you don't know when the gc will do it's thing, it is unpredictable, intermittent. If the gc is idle until you finished your preloading code, it works. The strangest part is that even if the gc clears the NetConnection object and the loading information goes berseck, you can still use the NetStream. It's there. It's readable and all, but the loading information becomes useless. The fix is easy. Just make sure you keep a reference to the NetConnection object, as a class property, anywhere the gc won't clean it up.

getting a third opinion

posted by
Arthur Debert

on

Tagged with:

3 comments so far.
Say something

Other months availabe in 2007

The complete blog archive

The latest entries

Subscribe to comments on this entry: rss feed

Cloud me:
  • Greg in The Web does not need flash. on

    The web does not need Apple

  • Dane in The Web does not need flash. on

    To me, the key point in Flash's favor is productivity in creating rich experiences. Yes, javascript CAN create equivalent experiences, but it's a comparatively much more difficult process that requires ...

  • leef in The Web does not need flash. on

    Flash as a tool to develop cross platform applications is what I think is its future. And if it can also serve as a functional medium for users to use ...

  • Jesse in The Web does not need flash. on

    Despite the advances in Javascript, in many ways it is only catching up with actionscript, and while it is leading in some areas, javascript still needs a client. Whatever technology ...

  • Steven Wei in The Web does not need flash. on

    Very nice post. Your analysis was very thorough and I basically agree with all of your points.

    I have spent a couple years programming in Flash and have since moved ...

Feeds: Entries rss feed Linksrss feed Worksrss feed

A Django joint. hosted on Slicehost