Jeremy LaCivita

hack

Rich Media Hacker

Illustrations

USFSA Kayak theSlalom Cookies Free Skate BattleUS

Sketch

jawa mooch squash monkey chainsaw claws dragon hand2 head spread hand spidey hand marvin hand closed

Interactive

Carcassone Game Funky Valentine

« BattleUS: a Blast! | BattleUK II - Attack of the Cones »

Race Conditions in Flex VideoDisplay

Nov 14, 2007

The Flex mx.controls.VideoDisplay object is a double edged sword. If you’ve used it for anything complex, you’ve likely noticed that it gets very finicky under certain conditions. Thats really a shame, since it provides many useful features, like rtmp vs http connection management, bandwidth detection, and various optimizations to connection speeds to name a few.

On the Fan, we’ve occasionally had problems with playing lists of videos with VideoDisplay, and we’ve had to jump through a few hoops in order to continue to use it so that we’d still get all its benefits. The problem generally consists of the VideoDisplay getting into a state where it stops responding to subsequent calls to load() & play().

We had worked around most of these by moving around our code to avoid apparent race conditions in VideoDisplay, and we even had to monkey-patch the VideoDisplay & VideoPlayer classes to get around a problem were it would load the netstream twice for the same video and you’d get a double/echoing audio stream. While working with one of our partners recently, we came up against another bug in VideoDisplay that we couldn’t get around. This time it was throwing an error like this:

ArgumentError: Error #2126: NetConnection object must be connected.
  at flash.net::NetStream/construct()at flash.net::NetStream()
  at VideoPlayerNetStream()[E:\dev\flex_201_borneo\sdk\frameworks\mx\controls\videoClasses\VideoPlayer.as:2883]
  at mx.controls.videoClasses::VideoPlayer/createStream()[E:\dev\flex_201_borneo\sdk\frameworks\mx\controls\videoClasses\VideoPlayer.as:2712]
  at mx.controls.videoClasses::VideoPlayer/_load()[E:\dev\flex_201_borneo\sdk\frameworks\mx\controls\videoClasses\VideoPlayer.as:2170]
  at mx.controls.videoClasses::VideoPlayer/load()[E:\dev\flex_201_borneo\sdk\frameworks\mx\controls\videoClasses\VideoPlayer.as:1486]
  at mx.controls::VideoDisplay/load()[E:\dev\flex_201_borneo\sdk\frameworks\mx\controls\VideoDisplay.as:1361]

It actually involves not only VideoDisplay but also VideoPlayer (which VideoDisplay has an instance of) and even NCManager (which does some of the stuff mentioned above). My counterpart at the other company wasn’t seeing this error in his test environment, but eventually we realized what the crucial difference was: autoplay was set to false in the Fan, while it was left to its default (true) in his test player.

Since he had it working with no problem, i decided to see what would happen if i left autoplay at its default value of true.

Well, there were some side effects related to videos playing before i was ready for them, however the broken state of VideoDisplay went away! Now I simply pause the VideoDisplay right after i set the source to simulate having autoplay set to false. This has the added benefit of buffering the movie right away instead of later on, so i’m pretty happy with the solution (although i think VideoDisplay should do that anyway if it was written properly)

Update: here’s the code we used to patch mx.controls.videoClasses.VideoPlayer:

public function ncConnected():void {
  if (_ncMgr == null || _ncMgr.netConnection == null)
    setState(CONNECTION_ERROR);
  else{
    if (!alreadyLoaded) {
      alreadyLoaded = true;
      createStream();
      setUpStream();
    }
  }
}

Obviously we also added a variable declaration for alreadyLoaded, and we also reset it to false in the _load function (you can’t miss it, there’s a ton of variables getting reset in the function)

Update: here’s a screenshot of my project structure showing how to “underride” the adobe class.mx_packages.png 

tags

The Fan, flex, hack

15 Responses to “Race Conditions in Flex VideoDisplay”

“Some members in the Ruby world started adopting the term duck punching in lieu of monkey patching.” - Wikipedia

As much as I love the term “monkey patching” I’m really tempted to start calling it “duck punching” even though we don’t do ruby.

Could you please provide some insight into what your monkey patch did? I’m having the same problem and I’m having a hell of a time trying to pin it down.

Thanks!
Gary

i’ve updated the post with the details of my workaround.

i’ve improved it a bit since i wrote my post, and at this point, only VideoPlayer needs to be monkey-patched.

chakrit

Almost slipped over the deadline because of this load()/play() bug.

thanks for the post!

Chris Bray

When you say that you patched VideoPlayer, do you mean that you modded the source and recompiled the flex sdk?

@Chris,

almost. you can compile individual classes from the SDK into your own SWF, to override just those classes. Just create the adobe package structure for the class you want to “patch” in your project and it’ll override the SDK version for your app.

Chris Bray

So, for the case of VideoPlayer would I include the entire source for the VideoPlayer class?

yeah, and any assets it includes

Chris Bray

Thanks so much — I have it working. What a great feature.

[…] http://www.jlacivita.com/2007/11/14/race-conditions-in-flex-videodisplay/ […]

chrislaan

gorgeous… thanks a lot!

Salick

Hey,

what do u mean by “Just create the adobe package structure for the class you want to “patch” in your project”?

Could u explain the stages I should do exactly after editing the VideoPlayer class?

Gary Black

Thanks for the information…

It certainly helped me to understand some of what was going on.

To help the other guys, specifically Salick’s problem - check out my blog at http://flexissues.blogspot.com/
http://flexissues.blogspot.com/

I found both this post and the bug fix one at adobe which basically got the dual stream problem sorted out.

I have included 2 zip files, both with the package structure intact for Flex2 and Flex 3 builds with full instructions on how to do this…

Cheers

I’m having the issue with VideoDisplay object loading the netstream twice.

How did you resolve this, bug ?

Jorrit

I am working on an AIR application with high resoution video files (f4v files, 3000Kbps). Files are played fast after each other.

I have had two issues, one that seems like another race condition. I read cue points from the f4v file by reading XML data and parsing cue points from it. These CuePoints are added to the CuePointManager.

CuePointManager has a function called dispatchCuePoints. A check is performed wether or not the list of cuePoints is not null. If it isn’t, a loop is performed. But in that loop cuePoints got set to null when I swapped a video. I added a check in the loop, to see if cuePoints got null while looping.

And another issues I had was with getting back into loading state quickly after the playing state was set. Due to this, no complete events were received anymore. I added in VideoPlayer.httpOnStatus under “NetStream.Play.Stop”, before httpDoStopAtEnd(), the case LOADING. Be careful with this one though, I think this fixed an application specific error.

Hope this helps for those encountering the same thing.

Leave a Reply