I’ll be speaking at Adobe MAX 2009

June 29th, 2009

It’s Official. I’ll be giving a talk at Adobe MAX 2009 entitled:

“Creating Workflow tools for the Flash IDE”.
October 6 at 01:30PM

This should actually read “Creating Flex Based Workflow tools for the Flash IDE”, but that bit got lost in translation somehow. The session will cover using Flex to extend the Flash IDE in the form of Flex applications running custom panel windows. If you were to look at Flash panels over the years they’re typically built purely in Flash using a very limited Flash component set. Worst of all, they don’t have a liquid layout. Of course Flex has layout management, but the framework also makes it easier to create complex applications to help automate your daily tasks. From there you can do things like integrate online content consumable through web services, communicate back with online systems (be they task or asset management systems), and automate the manipulation of items on your documents stage.

Keep an eye out as I may be posting more details in the weeks to come, and if you’re planning to stop by, let me know :)
Read more…

ian News

An asynchronous, vector optimized JPEG encoder

May 22nd, 2009

Thibault Imbert’s post earlier today showed how the use of the new Vector class in Flash Player 10 could significantly speed up the AS3CoreLib JPEGEncoder class. Coincidentally I’m working on a project right now that uses JPEGEncoder to save an image of a web page so naturally I switched the old array version out for the vector version. The images captured are typically around 1000×2880 so I need to be able to prevent any locking up of the flash player and provide progress for the encoding. That being said, I’ve put together a mash-up of the original asynchronous JPEGEncoder class with the new Vector based one.

As with the previous version the actual speed of the asynchronous encoder is dependent on the number of pixels you can crunch per iteration. The higher you set it the faster it will be, but if you set it too high you’ll run into latency issues much like you do with the standard encoder and larger images.

If anyone cares to test the effect the asynchronous addition has on the speed of the vector encoder I’d love to hear the results - but I don’t have time at the moment :)

JPEGAsyncVectorEncoder

(You’ll find a new class under “util” which includes the Vector optimizations)

ian News

Saving snapshots of HTML content in AIR

April 29th, 2009

This can actually be done with any component that implements IBitMapDrawable, but I’m going to show you how it can be done with an HTML component specifically because, well, its cool. Feel free to use it to capture images of your web creations for portfolio purposes (in fact, I think I might just polish this up and make an real app to do just that).

To do this we just need an HTML component from which we can generate bitmap data using the BitmapData.draw() function. The bitmap data can then be encoded into a JPG ByteArray using the JPG encoder class available in AS3CoreLib. Once we’ve done that its just a matter of using a FStream to write those bytes to a File object with the appropriate extension (.jpg in this case). My example here writes the image to the desktop, but just a bit more code you could browse for a custom save location.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" 
	verticalScrollPolicy="off" horizontalScrollPolicy="off"
	width="1024" height="768" 
	paddingLeft="0" paddingRight="0" paddingBottom="0" paddingTop="5"
	backgroundColor="#000000">
 
	<mx:Script>
		<![CDATA[
			import mx.managers.CursorManager;
			import mx.controls.Alert;
 
			import com.adobe.images.JPGEncoder;
			import flash.display.Bitmap;
			import flash.display.BitmapData;
			import flash.utils.ByteArray;
			import flash.filesystem.File;
			import flash.filesystem.FileMode;
			import flash.filesystem.FileStream;
 
			private function takeSnapShot() : void {
 
				var snapShot:File = File.desktopDirectory;
				snapShot = snapShot.resolvePath("AIRSnapshot.jpg");
 
				var fStream:FileStream = new FileStream();
				fStream.open(snapShot, FileMode.WRITE);
 
			    var bitMapData:BitmapData = new BitmapData(htmlContent.width, htmlContent.height, false);
 
			    var encoder:JPGEncoder = new JPGEncoder(80);
				var rawBytes:ByteArray = encoder.encode(bitMapData);
 
			    fStream.writeBytes(rawBytes, 0, rawBytes.length);
			    fStream.close();
 
		    	Alert.show("Snapshot Saved to Desktop");
		 	}
 
		]]>
	</mx:Script>
 
		<mx:Button label="Take Snapshot" click="takeSnapShot()" color="#FFFFFF"/>
		<mx:HTML id="htmlContent" location="http://devote.your.life.auricom.com" width="100%" height="100%"/>
 
</mx:WindowedApplication>

Hit this link link download the source and try it out.

ian News

SporeView gets an honorable mention!

April 28th, 2009

sporeview_honorable
Maxis sent me an email tonight letting me know that my Spore API contest entry, SporeView, has won an honorable mention. I’m actually really relieved to have gotten some recognition because

  1. I lost a lot of sleep making SporeView
  2. The winning entries were, how do you say, lame

OK, they weren’t that bad. The Augmented reality app that won the competition is actually very cool despite being a little unpolished. It builds wireframe skeletons from the vector data available in the creature xml which is no doubt impressive. If the mesh data for the creature parts themselves were made available through a service then PaperVision 3D could have actually been used to build an accurate model of a creature. I looked into this when thinking up ideas but realized mesh data wasn’t available moved on (thinking that wireframe skeletons were just too plain to do Spore creatures any justice). I hate to say it but the augmented reality portion of this app is, well, a gimmick. AR is cool, but its being done to death right now. As a developer I see trends come and go so I just have to laugh a little at the AR craze. I hate to think that the AR portion of this really pushed it over the top since the wireframe rendering is the big accomplishment here. Regardless, big up to to Aaron Meyers and his Spore Skeltons app.

The second and third place winners were a non-asynchronous Javascript and Flash creature browser (I thought asynchronous web apps was just expected nowadays) and a .NET based desktop app that isn’t cross-platform and doesn’t warrant a desktop-app (plus building non cross-platform apps from web-services defeats the purpose of a service based API in my opinion). Not what I would expect out of a silver and a bronze.

I know I sound like a sore loser here. I really am happy to have gotten an honorable mention. I just build apps day in and day out so I have a lot of strong opinions about what makes an application actually good (being in Flex is always a good start!). In any event, much thanks to Maxis for putting on the competition and we’ll see if I can’t find the time to continue to add new features to SporeView.

ian News

SoundCloud audio in your vBulletin forums using UBBC

April 28th, 2009

Here’s something quick I wrote up for a friend. It allows you to embed SoundCloud audio files into forum posts. Just put the code into the header or footer of your forum. This was tested on ProBoards.com which appears to be a hack-up of vBulletin but it should work for the newer versions as well.

<script type="text/Javascript">
// SoundCloud UBBC for Posts by Ian McLean
 
var perPage = 20;
var ubbcURL = "http://a1.soundcloud.com/images/soundcloud-logo-simple.png";
 
// No need to edit
var aTD = document.getElementsByTagName("TD");
var curr = 0;
if(location.href.match(/action=display/i)){
    for(a=0;a<aTD.length && curr < perPage;a++){
        if(aTD[a].colSpan == 3 && aTD[a].vAlign == "top" && aTD[a].firstChild.nodeName.match(/^(#text|hr)$/i) && aTD[a].innerHTML.match(/\[sc\](.+?)\[\/sc\]/gi)){
            curr = curr+parseInt(aTD[a].innerHTML.match(/\[sc\](.+?)\[\/sc\]/gi).length);
            aTD[a].innerHTML = aTD[a].innerHTML.replace(/\[sc\](.+?)\[\/sc\]/gi,'<div style="font-size: 11px;"><object height="81" width="100%">  <param name="movie" value="http://player.soundcloud.com/player.swf?track=$1"></param>  <param name="allowscriptaccess" value="always"></param>  <param name="wmode" value="transparent"></param>  <embed allowscriptaccess="always" height="81" src="http://player.soundcloud.com/player.swf?track=$1" type="application/x-shockwave-flash" width="100%" wmode="transparent"> </embed> </object> <div style="padding-top: 5px;">');
        }
    }
} else if(document.postForm){
    if(location.href.match(/quote=/i)){
        var m = document.postForm.message;
        m.value = m.value.replace(/\[sc\].+?\[\/sc\]/gi,"");
    }
    if(document.postForm.color){
        var h = document.createElement("span");
        h.innerHTML = "<a href='javascript:add(\"[sc]\",\"[/sc]\");'><img src='"+ubbcURL+"' border='0' alt='SoundCloud' /></a>";
        document.postForm.color.parentNode.appendChild(h);
    }
}
</script>

Now use [sc]my track name[sc] in your forum post to include a SoundCloud file.

ian News

Some nerd humor

April 7th, 2009

I wrote this lovely bit of code today whilst confused and frustrated working on a particularly messy command…and its just plain funny.

for(var i:int = 0; i < localSubSwfArray.length; i++){
 
		if( localSubSwfArray[i] is LocalFile){
			getDetailsArray.push(LocalFile(localSubSwfArray[i]).uri);
 
			 localFileArray.push(localSubSwfArray[i]);
 
			 localSubSwfArray.removeItemAt(i);
			 i--;
		}
               else panelForTransport.SubSWFs.addItem(localSubSwfArray[i]);
}

I needed to push items into a one array if they were of a particular type, otherwise add them to another array. Thing is I somehow saw it necessary to remove the item from the original array (with no real purpose), which screwed up the positions for the next iteration of the for loop. My fix? Throw a decrement in there to offset it! This actually works despite how unnecessarily confusing it is, it just wasn’t the right solution.

For all you project managers out there, this is a perfect example of why Agile suggest developers never code more than 6 hours a day. Fat chance that any of us will ever see that implemented, but I still like to mention it.

ian News, Projects

Spore API contest entry

April 6th, 2009

Alright, its time to unveil how I’ve been spending my evenings for the last couple weeks. The guys over at Maxis recently released the Spore API into the wild and are holding a competition for the best application. I decided to make an entry of my own, so here it is: SporeView

SporeView

SporeView is a app built in Flex that allows you to browse the Spore universe outside of the game. You can browse assets, users, and view SporeCasts. Its also available as an AIR app that can be run from your desktop.

Admittedly I’ve played a rather small amount of Spore but I’m hoping to find the time to change that. After making this app and browsing some of the popular community creations I’m kind of inspired to make some of my own. Spore users have made some really incredible stuff using the creature creator that I didn’t think was possible. Hats off to you Spore community, keep up the good work. Hopefully I can join your ranks soon.

ian News

AIR 2.0 needs this stuff

March 30th, 2009

Word on the street is that Adobe is gathering feedback for the release of AIR 2.0. I think AIR is and was a great addition to the Flash platform. There following are things I feel AIR really needs to succeed as it continues to mature:

  • Framework embedded executeables (think projectors)
  • A fully customizable AIR installer for one click installs
  • The option to use a third party installers
  • C level extensibility
  • Less branding

When I run and app it feels the most “real” and “professional” to when I’m unaware of its underlying technology. The average user doesn’t care what their app is built with, just that it works well and looks nice. Sadly AIR currently lacks transparency and I can’t give this experience with Flash. I would have to build an application in a low level languages or a scripting languages where apps can be distributed with an embedded runtime and then use a scriptable installer to make per platform distributables. Visually none of these technologies are as advanced as Flash and Flex, and they certainly aren’t as rapid when it come to development. This is all the more reason why AIR needs to be able to produce “real” applications.

The desire of developers who aren’t hard-core native application developers is to make traditional desktop apps using technologies that they’re already familiar with. They want to use non-traditional means, but still compete in the same marketplace as traditional app developers. The issue is that apps that are created using these technologies often lack transparency and are constant reminder that they aren’t truly traditional apps. In the case of AIR, the air specific installation process makes a clear distinction between and AIR app and a standard app. As a user the AIR managed installation process is quite unlike that of any other application you’ve ever installed. This sort of thing makes it very difficult for the user to suspend his/her disbelief that this is actually a real application (much in the same way that Photoshop or Word are real application).

The next issue is runtime distribution. Download an popular app, Firefox for example. Run the installer. At any point during this process were you asked to download and install yet another file in order to run it? No, and this is the experience that people have come to expect when installing something. Consequently this is the experience AIR (and others) should emulate. Having to explicitly download a runtime and wait through a framework specific installation process in order to use an app and two more steps than most non RIA enthusiasts are willing to take.

The need for C-level extensibility in an application framework is a pretty easy one to make. Any and all intensive calculations are better off-loaded to low level languages. Extensibility also allows for custom functionality beyond what the framework provides.

I certainly don’t seek to discredit AIR in its current form (at least not entirely). One click web installs makes deploying desktop apps that provide out-of-browser access to online services dead simple, and its cool. After all, Flex is a RIA technology so it was only natural that the current model of AIR was RIA centric. My hopes, however, are that the next steps for AIR will be more in the direction of a full fledged application framework.

ian Air

D.Y.L gets a fresh coat of paint

March 17th, 2009

I’ve been taking some time over the last few days to upgrade wordpress and give the blog a new look. I also have a twitter plug-in installed now so everyone can have a portal into my often whimsical ramblings. So enjoy..or simply tolerate it.

ian News

Rovio (and router) network configurations for FIOS

November 7th, 2008

I’m posting this up here for my fellow FIOS subscribers, although this could really also serve as an example to anyone trying to set up the proper port forwarding on their router despite the obvious difference in admin utilities.

The Verizon standard issue Actiontec MI42WR router can be rather problematic for the simple reason that its just not a great router. For those of you who aren’t on FIOS and might wonder why you would continue to use the router, it uses a technology called MoCa that allows set to boxes to get an IP over coax and consequently directory listings and on-demand content rely on this. There are of ways around this, which I’m willing to discuss with anyone who’s interested, but there a 99% chance that your FIOS is set up like I just mentioned.

First thing to note about Verizon is that the Actiontec is configured to use port 80 for remote administration. Even if you disable remote administration it doesn’t release the port. In fact the only way to release it is to actually change the the primary remote administration port something else regardless of whether its enabled or not. This is somewhat of a hassle to do. Thus, you really need to set your Rovio to a different port, or have an external port forwarded to port 80 on the Rovio if you want to have any hope of accessing it outside of your LAN. I’ll only demonstrate the former here. Secondary http (8080) its probably the most appropriate port for the job, but in my case I already have apache running on 8080 so I’ve just arbitrarily chosen to use port 5000.

Once you’ve gotten initial access to your Rovio’s web based control panel using its default 192.168.1.18 IP, open up the settings. They should look something like this.

rovio_network_config.jpg

Setting up a static IP is required in order to set up the port forwarding on the Actiontec router. I’ve chosen 192.168.200 here. You’ll also see that the Web Port is 5000 instead of 80. Again this can be any port of your choosing so long as it doesn’t conflict with another service that already listens on that port.

At this point put in your Rovio’s IP address (in this case, http://192.168.1.200:5000) to your web browser and test that its responding on the port of your selection. Currently IE 6.0 and up is the only browser that currently supports video as well as audio so this is what you need to test with. Most issues with audio and video not working in IE when connecting from outside of your network are port forwarding issues. If Rovio’s audio or video does not work over your LAN then there is probably an issue with the Rovio itself.

Now move over to your router. Unless you’ve changed it the Actiontec admin utility can be found at http://192.168.1.1 . Go into the firewall settings and select port forwarding. First you need to create an entry for the IP that Rovio is manually configured to use. Then set up the rules to look like exactly like this. Notice that we’re forwarding port 554 for the Rovio’s RTSP service to communicate on. This is required for video and audio to work in IE after you’ve installed the ActiveX control. Make sure you hit apply after each screen so the changes are committed.

rovio_actiontec_port_forwarding.jpg

Now, assuming that you’ve set up dynamic dns you should be able to connect to the Rovio from an outside network with no problem. While the dynamic dns settings on the Rovio are a nice feature this should really be set up on your router assuming it supports communicating with a DDNS. Alternatively you can download and run a DDNS auto updating utility and run it on a server or some machine that is frequently online. For instruction on setting up dynamic dns with the Actiontec router see this post.

ian News