Friday, June 08, 2007

Phoenix FUG

Phoenix has started a Flex User Group! I'm very excited about this. Finally I can bore someone besides my wife with my rantings about how awesome Flex is.

Our first meeting was rather low-key; as expected it was mostly a meet-n-greet where a lot of people handed out business cards and we all got to see that there were other people like us out there. Somebody from Adobe gave a brief Breeze talk thanking us for showing enough interest in the platform to form a group and talking a bit about the Flex 3 Beta. I understand we're going to have some more people down from Adobe in the flesh in future meetings.

I was interested (though not at all surprised) to discover that most of the guys that drifted into Flex actually came from the Java world rather from Flash. It seems that a lot of us Flash guys get a bad rap from other disciplines for being hacks and not knowing how to program. Hopefully the involvement of programmers from other walks of life in groups like this will bring some much needed attention and validation to our platform and to our code.

If you're in the valley area then I hope to see you there!

Thursday, May 24, 2007

F8 - It was just Fate


So in case you haven't been on the internet lately, there's this thing called Facebook. It's kind of like MySpace, but done right.

Well Facebook has just made a huge announcement. And Terralever, the company I work for, has been fortunate to be a part of it.

Essentially, Facebook has opened up their network for us developers to write against. We now have a HUGE amount of social data that we can use, and have our applications installed right on the user's page. "Click" and your friend just installed it. "Click, click" and two of their friends installed it. No copy + paste cryptic HTML like on MySpace. It's viral social networking at it BEST.

So we've got this awesome API to get this data. As a Flash developer, my goal was to get all of this information onto the Flash platform. The services are provided as (wonderful) REST service calls, but the APIs that are provided to us are all written in PHP and Java. Neither helped me very much . . .

So we had to roll our own. We've got a pretty nice start on it too! More details are going to follow soon, but if you're interested please drop me a line and we'll make sure that API is available to all you Flashers out there and keep you up-to-date as it matures.

I'm at Facebook's lauch event, and hanging out with a bunch of other devs now at their Hack-a-Thon. A VERY nice thing that Facebook has done for us, giving us direct access to the devs that actually wrote this platform!

I'm back to hacking with these other guys, but I'll post some more soon!

Wednesday, May 09, 2007

The Video War

It's about to begin in earnest. Some Battles have already been fought. The time we've all been waiting for, the time we've all been talking about for a decade now, is finally here. The real battle is about to begin.

We're going to see two different sides of the war going on simultaneously; the hardware battle for living room dominance and the software battle for distribution systems. We've got some big players in this fight for video dominance and everyone wants to be the team that puts video/television (and their ad revenue stream) in front of consumers.

The hardware battle will rage on for years. Eventually video hardware and software systems will merge and the battle will continue. But that's not what I'm here to talk about right now.

The battle that is going to be fought this year that I'm interested in is the battle for distribution. Google showed us just how important the video-on-pc realm is with its enormous purchase price of YouTube. There are dozens of other video sites popping up all over the place. If you want to stay in the browser, then that's fine content for you. But the browser is going to go away as we know it. No time REAL soon I think (that's a topic for another post). And the king of the video delivery isn't going to be a website.

Enter the video player players: Joost, Adobe Media Player, and my favorite The Democracy Player. Apple has already gotten started as well with video delivery on iTunes and TiVo has got sime fingers in the soup with some download-able movie content, though that's kind of entering into the realm of hardware.

But Joost, AMP and Democracy are the players I see with the biggest potential. An important aspect of these players is cross-platform-ability. All of these are either platform agnostic (AMP runs on Apollo, a runtime for Windows, OSX & Linux; Democracy is tooled in Mozilla's XUL platform which runs on anything you want to throw it on) or has at least been built for the up-and-coming OSX platform.

How these players get their content to the people work in slightly different ways. The way the user interacts with these systems works in different ways. How content creators get paid for their content works differently. What advertisers can do to get their product in front of people is very different.

Joost is a pretty popular topic of discussion right now and I've been fortunate enough to do a bit of beta testing on the platform. I wish I could say I was impressed. They're trying to offer on demand video using peer-to-peer technology to move the content around. Because I'm pretty much "streaming" the video the quality really suffers. The interface is pretty cool, and if the bandwidth weren't an issue Joost could have some real promise. But until that happens I'm just not going to get excited about it. I'm picky and I've gotten used to my HD content.

This is where the other two options I'm excited about come in. AMP and Democracy both operate on a subscription model, rather than an on-demand model. I know the kinds of things that I like to watch. All I have to do is select the feeds to the content I'm interested in and the player will pull down the content as it becomes available. I'm not expecting to watch it right away, I'm more then willing to let the file come down from the server; or even from a .torrent or other peer-to-peer technology. When it's available to me (in all of it's 720p artifact free glory) then I'll watch it at my leisure.

Now Democracy is great; but it's just a little geeky. Subscribing to some feeds is a little tricky sometimes. It's completely open so that everybody can make a feed and have their own channel. But it doesn't have much in the way of corporate backing. This is where AMP is better and why I'm really looking forward to it. AMP's feeds allows content deliverers to really customize the experience. To brand it, to put in the station bugs, or non-interupting advertisements. The ability to "shop" directly from the video interface (a feature longed for by those with ad dollars to spend) becomes quite possible in AMP. And Adobe is on the hunt for some big video companies to get some content in there so that Adobe Media Player is THE place to be for video content.

XML feeds are obviously going to be a very important aspect to this battle. PodCasts have really taken off for audio, and video podcasting is really starting to gain momentum. Even content from content websites can be gotten from feeds (such as YouTube feeds). What the players allow the users, and more importantly the content creators, to do with this information is really how the battles will be fought.

I'm really looking forward to this fight!

-JC

(For some more very good reading on the topic, check out Nicholas Reville's essay on RSS and video distribution)

Thursday, March 29, 2007

Wizard Binding (binding things up that don't want to be bound)

Flex Data binding ROCKS. Doesn't it? The concept and execution is AS is pretty darn easy and very powerful. But binding things in MXML? Absolutely rocks. So fast and easy.

But it sure does suck when it doesn't work like ya thing you should.

I've been building a wizard lately. It seemed to me like it would work out awfully well if I could just bind certain properties to my "next" button based on the state the wizard is in. Once the user has made the correct decision (the item is no longer null, my list is no longer empty, etc) the next button would just light up and away we would go!

I bound them as one would expect using MXML but it just didn't work out for me.

The bindings just wouldn't execute at all. But I want bindings. I NEED bindings. So I decided to bind them "by hand". (Any time I have to do things a longer way than I feel I should it's always "by hand".)

I'm a big fan of code behind. Code just doesn't belong in MXML if we can help it. So for my wizard of course I have a code behind class. In that class I have a function that I use to change state (rather than just calling currentState="newState";). In this function I handle my next button bindings (and any other bindings that I need to happen when the state has changed and my new items need to be tied up). This is what it looks like:


private function navigateToState(newState:State):void
{
this.currentState = newState.name;
PopUpManager.centerPopUp(this);

//reset next button
nextButton.enabled = true;
if(nextWatcher)
{
nextWatcher.unwatch();
nextWatcher = null;
}

if(currentState == "albumSelection")
{
nextWatcher = BindingUtils.bindProperty(nextButton, "enabled", this, "selectedAlbum");
BindingUtils.bindProperty(this, "selectedAlbum", albumSelector, "selectedAlbum");
}

if(currentState == "imageSelection")
{
nextWatcher = BindingUtils.bindProperty(nextButton, "enabled", fileList, "length");
}
}

By the way, nextWatcher is a class variable of type ChangeWatcher. This is returned from a binding and can use it to control an existing (or create a new) binding. It's a rather powerful class and I definitely plan to talk some more about it later!

Please if anyone else has ANY ideas on how I can do this with MXML then I'm all ears. I do really love shortcuts. Lazy programmers make good programmers right?

-Jason Crist

Wednesday, March 28, 2007

Flex is still Flash (adventures in preloading)

I sometimes forget that I'm still programming for Flash.

I'm very pleased with the Flex 2 framework. It's really enabled me to build some powerful applications that would have taken me a MUCH longer time in Flash. I've got all (most of) the benefits of many of the other languages+frameworks (java+swing comes to mind) and a host of others that really make application development a breeze. XML view declaration, while certainly not an original idea (I was using XUL before its MXML cousin came of age . . .) is very well executed and it's (mostly) clean tie in to ActionScript and the new component architecture has really made development a much more efficient process.

So it's sometimes really easy to forget that I'm still programming for Flash.

My first experiences with ActionScript 3 (like many others I'm sure) has been for Flex 2. It's easy to forget all about timelines. It's easy to forget about all of the hacks that we've seen (and used) to get things to do what we want in our AS2 and (and if you can remember that long ago or are unfortunate enough to work on those projects that still exist) AS1 projects. All those frame based commands. All that (shudder) timeline code. All those onEnterFrame functions buried in our MovieClips. We all did it. Hopefully we eventually learned better, but we all did it.

It's SO great to live in a development environment that has no visible concept of the timeline. And for a while, I just forgot that it existed.

But then I started creating a custom preloader. How did we used to do that? Well, we put as little as we could on frame 1, threw up some kind of animation, maybe a loading bar and when we were all done we went to frame 2 and launched our app.

Seems the same thing is happening in Flex 2.

It makes sense I suppose. But that very Flex looking loader bar was something that I just thought of as magic 'till I looked into it.

Obviously the flex framework is going to be a large chunk of what needs to be downloaded. (BTW there is talk that the framework will eventually be a download-once accompaniment to the Flash plugin which is gonna help make our .swfs quite a bit smaller!) And all of the graphics, skins, styles, etc are gonna need to be downloaded. Defining the custom loader is cake; just define the 'preloader' attribute in your application MXML. The code generated (which I think is always just a little magical when I look at it) has the SystemManager load the class you specify the the attribute. The mx.managers.SystemManager is the first piece of the framework that is loaded and is purposefully kept as lightweight as possible. Take a look at the code sometime (dig into the SDK/frameworks/source folder to get at it). It's good stuff.

And the preloader itself needs to be kept as lightweight as possible too. Just a sprite that implements IPreloaderDisplay. No flex framework goodness, just good 'ol fashioned primitives. Draw some shapes, maybe throw up some text. But ya got to keep is simple yo. Extending DownloadProgressBar is a nice and easy way to get all of the IPreloaderDisplay stuff taken care of for you though if you're not going for the absolutely slimmest loader possible.

Just a small bit of code to get you moving in the right direction if you want to do one of these yourself. . .

< project:projectApplication
project="project.*"
mx="http://www.adobe.com/2006/mxml"
preloader="project.loaders.ProjectSplash"
layout="absolute" >
. . .


Something you may notice about the above MXML is that instead of using an node, I've used something else. I really hate having more than an import and a couple lines of code in my MXML, so for anything else I'll extend and code behind. So I've got a class called ProjectApplication that extends mx.core.Application.

And here is my preloader:

package com.terralever.loaders
{
public class SplashScreen extends DownloadProgressBar
{
// VARIABLES //////////

private static var instance:SplashScreen;
private var image:Loader;

// CONSTRUCTION //////////

public function SplashScreen()
{
super();

//load the image
image = new Loader();

image.loadBytes(getSplashGraphic());
addChild(image);

image.addEventListener(Event.RENDER, onRender);

this.alpha = 0;
var fade:Fade = new Fade();
fade.alphaFrom = 0;
fade.alphaTo = 1;
fade.duration = 1000;
fade.play([this]);

}


// GETTERS and SETTERS //////////

override public function set preloader(preloader:Sprite):void
{
preloader.addEventListener(ProgressEvent.PROGRESS, SWFDownloadProgress);
preloader.addEventListener(Event.COMPLETE, SWFDownloadComplete);
preloader.addEventListener(FlexEvent.INIT_PROGRESS, FlexInitProgress);
preloader.addEventListener(FlexEvent.INIT_COMPLETE, FlexInitComplete);
}

// PUBLIC FUNCTIONS //////////

// PROTECTED FUNCTIONS //////////

/**
* This returns the default splash graphic.
* Override this method to define a new graphic.
*/
protected function getSplashGraphic():ByteArray
{
[ Embed(source="assets/splash.png", mimeType="application/octet-stream") ]
var graphicClass:Class;
return new graphicClass();
}

protected function SWFDownloadProgress( event:ProgressEvent ):void
{
//TODO
}

protected function SWFDownloadComplete( event:Event ):void
{
//TODO
}

protected function FlexInitProgress( event:FlexEvent ):void
{
//TODO
}

protected function FlexInitComplete( event:Event ):void
{
dispatchEvent(new Event(Event.COMPLETE));
}

// PRIVATE FUNCTIONS //////////

private function onRender(e:Event):void
{
this.x = this.stage.stageWidth/2 - this.width/2
this.y = this.stage.stageHeight/2 - this.height/2
}

}

All it does is throws up a graphic instead of the loader bar. But it won't be hard to get it play a dancing bear instead. ;)

-Jason Crist