06.24.09

Canada finally progressing into the digital age

Posted in Canada, cool, copyright at 11:30 am by rbezemer

Michael Geist, the crusader of Canadian copyright has a interesting story posted here.

Finally it looks like the Conservative goverment has realized how backwards the DMCA is and looks like they might finally be progressing in the right direction. Either that or in this recession the lobby groups funding has dried up…

I love the fact that both the Industry minister and Heritage minister both lament the fact we can’t be stuck in the past and the industry has to move forward or risk becoming irrelevant.

05.21.09

Flexing the Youtube Chromeless player

Posted in Flex Code, youtube at 1:29 pm by rbezemer

Getting youtube and flex / flash to work together can be a nightmare. Our original implementation ended up having us being forced to do “hack” youtube  to tease out the path the the flv and play that in a native flex video player interface. This solution works well and lets you have multiple videos playing inside your flex application at once, but unfortunatly youtube doesn’t like this idea at all. Over the last few months they have continuously been changing their paths to the flv so that any html scraping code to pull out the path is essentially worthless, unless you really like rewriting html parsing code every few days, we needed a better solution.

Youtube recommends using their chromeless player api . This player is great, you can embed it in flash and send it all types of commands with your own custom interface. However there is a catch… it’s written in ActionScript 2. I don’t need to go into the details of the problems of embedding as2 into as3 code as it’s documented all over the web, but basically this means we can’t use a nice stylish flex ui to send commands to the embedded player. The solution is not too complicated, we need to write an ActionScript 2 wrapper that uses a local connection object between the ActionScript 2 swf and the ActionScript 3 swf that it’s embedded in.

The code isn’t to complicated but it definitely takes a little bit of getting used to get your head around the local connection methods. There are a few third party api’s out there already that do most of the heavy lifting. The one I found most usefull was TubeLoc which seems to be youtube’s recommended embedding solution for Flex and ActionScript 3. However there was one massive limitation for our project… you can’t embed more than one video in your flash file at one time. This has to do with the id’s of the local connection object, and the complex communications methods that are used with them. You can see the list of problems people are having with it here , and tubeloc is by far the best of the third party solutions I could find.

Needless to say, I found a few out of the way forum posting that pointed me in the right direction an came up with this solution. One of the key fixes involves making sure you are only creating and initializing one local connection object at a time, if you start doing multiple ones at once, bad things start to happen. It’s a nearly fully featured youtube embedding library. If you need more functionality from the as2 wrapper, you will need a way to compile as2 code. I just used the trial version of Flash CS4 to build the as2 swf that is loaded by the flex app.

Anyway here’s the flex app, view source is here.

and here is the as2 code that gets compiled into ytPlayer.swf. I can’t take all the credit for it. I mostly just extended the code provided by http://yikulju.com/blog/?p=197. Most of the loading code is his, I just extended it to enable most of the advanced features of the youtube chromless player (such as video progress reporting, volume, etc…). Main thing to note is there are bugs with the volume controls when there are multiple videos, but this seems to be a youtube chromeless player bug and not a flex / flash bug.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
System.security.allowDomain('www.youtube.com');
System.security.allowDomain('gdata.youtube.com');
System.security.allowInsecureDomain('gdata.youtube.com');
System.security.allowInsecureDomain('www.youtube.com');
 
var loadInterval:Number;
var progressInterval:Number;
var ytplayer:MovieClip = this.createEmptyMovieClip("ytplayer", this.getNextHighestDepth());
 
var swf:String = "http://www.youtube.com/apiplayer";
 
var cn:LocalConnection = new LocalConnection();
 
var channel:String = _root.boxName;
var channelBack:String = _root.boxName+"Back";
var lastStatus:Number = -1;
cn.connect(channel);
 
ytPlayerLoaderListener = {};
ytPlayerLoaderListener.onLoadInit = function() {
	loadInterval = setInterval(checkPlayerLoaded, 250);
};
 
function checkPlayerLoaded():Void {
	if (ytplayer.isPlayerLoaded()) {
		clearInterval(loadInterval); // IMPORTANT - kill the interval
 
		ytplayer.addEventListener("onStateChange",onPlayerStateChange);
		ytplayer.addEventListener("onError",onPlayerError);
		loadIndicator._visible = false;
		progressInterval = setInterval(dispatchMovieProgress, 500);
 
		cn.send(channelBack,"onPlayerLoaded");
	}
}
//This reports the movie's state changes back to flex (playing, paused, etc..)
function onPlayerStateChange(newState:Number) {
	//do something when player changes state
	if(newState!=lastState)
	{
		lastState = newState;
		var event:Object = {eventName:"onStateChange",
							value:lastState,
							duration:ytPlayer.getDuration()/*,
							isMuted:ytPlayer.isMuted(),
							volume:ytPlayer.getVolume(),
							*/};
		cn.send(channelBack,"onStateChange",event);
	}
}
 
function onPlayerError(errorCode:Number) {
	//do something on player error
	cn.send(channelBack,"onError");
}
//Tell flex every few milliseconds that the movie playhead has changes
function dispatchMovieProgress():Void {
	if(lastState==1) {
		var event:Object = {eventName:"onMovieProgress", currentTime:ytplayer.getCurrentTime(), duration:ytplayer.getDuration()};
		cn.send(channelBack,"onMovieProgress",event);
	}
}
 
var ytPlayerLoader:MovieClipLoader = new MovieClipLoader();
ytPlayerLoader.addListener(ytPlayerLoaderListener);
ytPlayerLoader.loadClip(swf,ytplayer);
 
cn.pauseVideo = function() {
	ytplayer.pauseVideo();
};
cn.playVideo = function() {
	ytplayer.playVideo();
};
cn.stopVideo = function() {
	ytplayer.stopVideo();
};
cn.loadVideoById = function(id) {
	ytplayer.loadVideoById(id,0);
};
cn.destroy = function() {
	ytplayer.destroy();
};
cn.cueVideoById = function(id) {
	ytplayer.cueVideoById(id,0);
};
cn.seekTo = function(dataObject_p:Object) {
	ytplayer.seekTo(dataObject_p.seconds,dataObject_p.allowSeekAhead);
};
cn.setVolume = function(dataObject_p:Object) {
	ytplayer.setVolume(dataObject_p.volume);
};
cn.unMute = function() {
	ytplayer.unMute();
	dispatchMovieProgress();
};
cn.mute = function() {
	ytplayer.mute();
	dispatchMovieProgress();
};
cn.setSize = function(dataObject_p:Object) {
	ytplayer.setSize(dataObject_p.width,dataObject_p.height);
};

12.10.08

Interview with Bjarne Stroustrup

Posted in C++, Programming at 7:02 am by rbezemer

A good interview with Bjarne Stroustrup by James Maguire. He discusses the current state of CS graduates and the industry in general. Stroustrup is probably one of the few famous computer scientists I can relate to and I share many of his views on the state of computer science and the business world.

This advice is priceless:
Serious programming is a team sport, brush up on your social skills.
The sloppy fat geek computer genius semi-buried in a pile of pizza
boxes and cola cans is a mythical creature, best buried deep, never to
be seen again.”

That and he bears an uncanny resemblance to one of my favorite professors from University…

11.21.08

Meteor over Edmonton

Posted in Canada, cool at 1:12 pm by rbezemer

Very Cool that this happened right in my area, wish I was outside at the time and actually saw it instead of stuck in my office working.

Police dash cam of Meteor over Edmonton, Canada

11.05.08

Goodbye Micheal Crichton

Posted in Books at 11:13 am by rbezemer

Micheal Crichton Succumbs to Cancer

Wow, very surprised by this news. His books were a favorite of mine in my teenage years. He will be missed. Thanks very much for all the great stories, they were a joy to read with rich imaginary worlds to explore.

10.10.08

ActionScript 3 Photobucket API Basics

Posted in Flex Code at 8:11 pm by rbezemer

So by popular demand, and just because it’s fresh on my mind, I’ve revisited the Photobucket photoflow example. This version of the app goes a step further and uses the full blown ActionScript 3 Photobucket API. This API is actually relatively new and I was actually working on a similar interface to their API when they released theirs. Anyway the API details can be found here:

http://code.google.com/p/photobucketas3lib/

and of course you will need developer keys from Photobucket in order for this to work. Also since Photobucket does not have a crossdomain.xml yet, so you’ll need a local proxy if you want to use the coverflow container. I detailed a very basic one in an earlier post.

What I will do for this example is load a user’s album in Doug McCune’s photoflow container.

The Photobucket API is pretty straightforward to use. The work flow is basically the following:

1) log in to Photobucket with your developer keys

1
2
private var login:Login = new Login();
login.setConsumer(PhotobucketKeys.CONSUMER, PhotobucketKeys.PRIVATE);

2) Query for a user’s album information

1
 var _pbAlbum:Album = PhotobucketService.getInstance().albumFactory(user) as Album;

3) Request all the images from the album

1
 list.dataprovider = _pbAlbum.images;

4) List any sub-albums

1
subAlbums.dataProvider = _pbAlbum.sub_albums;

And that is basically it. There is some weirdness in their API in regards to the way they treat data providers. If you pass their return objects in as the dataprovider attribute to a display object you are fine, but it you want to do any advanced processing of the return values you have to do some work arounds to the way the return data to you. you can see the details in the source code below, but to put it simply they destroy the original dataprovider before they fill it with data so attaching listeners to the data provider does not work the way you expect.

Here’s the finished project. You can view the source here. To use it, enter a Photobucket user name that has public images available (private images will not be displayed) and press enter or click load. The user’s main album will show in the photoflow and all their sub-albums will show in the combobox. Select a sub-album to show it in the photoflow.

It’s pretty basic, but should give you a good starting point to jump into the Photobucket ActionScript API. My code is released under the Creative Commons Attribution license so anyone (personal or corporate) can use or modify it, just give a shout out to me if you do. Have Fun.

Stylesheets and mx_internal

Posted in Flex Code at 10:45 am by rbezemer

To make a long answer short… they don’t work well together.

basically if you want to set a style property on a CSSStyleDeclaration and you have mx_internal declared in your class (i.e. you are overriding a flex sdk component such as a button or list) then you will get weird ambiguous reference warnings like the following:

Id 1000: Ambiguous reference to setStyle

The solution is simple, instead of declaring use namespace mx_internal you just have to scope each of the variables or functions you want access to. i.e. mx_internal::adobe_hidden_variable. After doing this all your CSSStyleDeclarations::setStyle should work, however your code will now look very verbose with all the mx_internals all over the place.

more details can be found here.

10.09.08

Creating a php proxy for flash

Posted in php at 11:16 pm by rbezemer

So I’m planning on updating my photobucket samples, but I wanted a live flash file on my site instead of the crappy static image I had before. Unfortunaly since the coverflow component requires access to the BitmapData to create the reflection, loading any external images will throw an error. Since Photobucket doesn’t have a crossdomain.xml file yet, the best way to do this is with a simple php proxy to trick flash into thinking it was loaded from your own domain.

Since php is one of those languages I use, but not enough to remember the exact syntax I went searching online.The best example of this I could find was here. There were a few things missing from the script but not a lot. The one major thing I added support for was to verify that the request was coming from the same domain (Sorry but I don’t want everyone cutting and pasting my code and flooding my host with proxy requests and I’m sure you wouldn’t want the same either).

Once the proxy is in place usage is simple. in order to load an image from photobucket:
http://yourserver.com/proxy.php?url=http%3A//www.photobucket.com/some/link/to/image/image.jpg

Anyway here is my modified php code for a simple proxy:

proxy_php

Flex - Adding icons to a ToggleButtonBar

Posted in Flex Code at 2:28 pm by rbezemer

This was one annoying problem, I wanted a single icon on each button on my toggle button bar but for the life of me I couldn’t figure out what was going on. I had set the icon property in my buttonStyle in my applications stylesheet, but my icon was nowhere to be found.

Finally after pullling my hair out for a while, a trip to flexexample found me what I was looking for. The ToggleButtonBar (and any navigation component) uses the data provider supplied to it to pull out the icon resources for each button, so the dataprovider was overriding my stylesheet with null.

So easy fix was to just set a icon property on each item in the data provider with the image you are wanting to use.

here is the link to the example on flex examples: Flex Examples

Strength of Canada’s economy

Posted in Canada at 5:45 am by rbezemer

Ok, I know it’s a coding blog for the most part, but I thought this article was a excellent read on why Canada’s economy isn’t going down the drain like everyone elses. To me this is exactly how regulation of the banking industry should take place. For those to lazy to read the article (and I warn you it is fairly long) basically the Canadian governments policy is no we are not going to create money our of thin air for you, if you want to give out more loans you need to raise more capital on your own. This was their policy even when the Liberals we in power going back at least 20 years.

I am probably the furthest thing from an economist, but to me this makes much more sense than the American version which is, what you don’t have enough money well let me make some up for you…

Is it any wonder the deficit of our neighbors to the south is skyrocketing out of control. Which one is the socialist nation again?

« Previous entries

Bad Behavior has blocked 52 access attempts in the last 7 days.