Introduction

"And soon I will have understanding of videocassette recorders and car telephones. And when I have understanding of them, I shall have understanding of computers. And when I have understanding of computers, I shall be the Supreme Being!" (Time Bandits 1981)

Chris Ellis is a freelance Senior Flash Programmer, former Lingo Programmer and resident of London.

He has an MSc in Interactive Multimedia from Westminster University, graduating in 2000. He started programming at the age of 8 with a BBC Model B and a few books on BASIC.

What follows are some snippets from what he's currently up to.

Wednesday, 28 December 2011

RTMFP - Flex Mobile Redeems Itself

Peer-to-peer with Flex Mobile using RTMFP

As I was starting to doubt that Flex Mobile, I had an idea to link together my iPad with my Android phone. That was when I came across RTMFP. This is a really really simple way to connect multiple devices on the same wireless network. Just create a NetConnection and connect with 'rtmfp'. Then join a group and you're good to send and receive messages from all members of the group!

I created a simple app which will transfer images between the devices. I am sure this will not be allowed by Apple as it means you can transfer images without iTunes. Great for me though!

It should be possible to transfer any type of file between any devices that support AIR using this technique. It's not super quick (takes about 4 seconds to transfer an image) but could probably be speeded up by using FZip of something similar.

To use devices that are not connected via the same LAN is still possible, but you'd need to use Adobe's Cirrus.

http://labs.adobe.com/technologies/cirrus/

which is not currently available for commercial use.

Here is the code snippet to connect devices on the same LAN.

localNc = new NetConnection();
localNc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
localNc.connect("rtmfp:");


Then you need to join a group:

//define the group
var groupspec:GroupSpecifier = new GroupSpecifier("MyGroupName");
groupspec.ipMulticastMemberUpdatesEnabled = true;
groupspec.multicastEnabled = true;
groupspec.routingEnabled = true;
groupspec.postingEnabled = true;
//multicast ip should begin with 224 at least and port should be higher than 1024
groupspec.addIPMulticastAddress("238.254.254.1:30302");
//creates/joins existing group
netGroup = new NetGroup(localNc, groupspec.groupspecWithAuthorizations());
netGroup.addEventListener(NetStatusEvent.NET_STATUS, netStatus);


To send an image, you first need to turn it into a byte array:

var size:Rectangle = new Rectangle(0,0,loader.content.width,loader.content.height);
var byteArray:ByteArray = Bitmap(loader.content).bitmapData.getPixels(size);
byteArray.position = 0;
//send object to listeners
netGroup.sendToAllNeighbors({type:GALLERY_IMAGE, size:size,ba:byteArray});


When this is received it can be deserialsed. Here I display the image and attempt to save it to the gallery as well:

var byteArray:ByteArray = data.ba;
var bitmapData:BitmapData = new BitmapData( data.size.width, data.size.height, false,0x00000000);
bitmapData.setPixels(new Rectangle(0,0, data.size.width, data.size.height),byteArray);
myImage.source = bitmapData;
if(CameraRoll.supportsAddBitmapData){
//this will probably not be allowed by Apple as I believe it is against their control policy
trace('saving image to gallery');
var cr:CameraRoll = new CameraRoll();
cr.addBitmapData(bitmapData);
}else{
trace('cannot save image to gallery');
}


The full source for this experiment can be found here:

SOURCE

It's rough, but just shows the process of how to do the above.

Flex Mobile In Practice

So I need to make an a mobile app... should I build it natively twice (I can do a bit of Java dev, but would have to learn xcode a bit better for this), build it in HTML (not sure how jazzy it's going to look) or try out Flex mobile (should be easy for an AS3 developer right?! And it's going to work on a Blackberry Playbook without any extra work!).

So, I have spent a few weeks exploring the pros and cons of Flex mobile development. There are a number of decent tutorials that are out there, but I found that I still had to work out a lot of stuff for myself (like in the olden days), so I decided to note down a few things that I have learnt that may save someone a bit of searching.

This is written for experienced AS3 developers. The things I picked up are from my own research and inevitably a bit of searching on the web.

I usually don't work in Flex, just pure AS3. I decided to go down the Flex route for this though, mainly to save time as I didn't want to build common components from scratch and that Adobe are pushing 'Flex Mobile', which comes with a few nice inclusions such as (amongst other things) simple navigation and data storage.

The first thing I learnt was that in actual fact, although some components are, not all Flex components are actually 'mobile ready' at the time of writing. The list of ones that are ready, which should be kept up to date can be found here:

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/skins/mobile/package-detail.html

In the end I used Flash Builder 4.6 as it worked with Flex 4.6 out of the bag. I usually use FDT, but Flash Builder seems a bit better at dealing with MXML for the uninitiated, as it's always possible to switch to design view. There was also an issue whereby I couldn't get FDT debug to run on my device either, but it seemed to work ok from Flash Builder and I didn't have the patience to work out why.

The devices I was testing on were an HTC Incredible S and a Sony S Tablet. Setting up the Android SDK and getting them recognised by the ADT was pretty straight forward and there are lots of tutorials that will help you do this. The only minor pain was finding drivers for the devices, but this was just a case of googling around a bit.

Switching between layouts

When making any mobile app, effectively you are making an app that needs to look good in three resolutions (160,240 and 320 dpi) all of which run in two layouts (horizontal and vertical). So that's 6 different layouts per app!
From reading around, it seems that the best thing to do is to make the app for the smallest target dpi (160) and scale up. Bitmaps are handled slightly differently but I'll look at that later. By declaring the application dpi in the application's mxml constructor (not sure the correct name for this in Flex) as such:

applicationDPI="160"

Flex will then scale everything up automatically for the bigger dpi's.
One of the drawbacks of this are that it's probably not desirable for bitmaps to be scaled up. This is easily remedied by using the mutli-dpi source bitmap property of a Flex Image component.


<s:image id="myImage">
<s:source>
<s:multidpibitmapsource
source160dpi="assets/low-res/my-image.jpg"
source240dpi="assets/med-res/my-image.jpg"
source320dpi="assets/high-res/my-image.jpg">
</s:multidpibitmapsource>
</s:source>
</s:image>


All three images get packaged up into your application, but the one closest to the target applications dpi will be used. Simple.

One thing that I wanted to do was to be able to change the actual layout when there were different dpi's and different orientations. The 'cleanest' way seemed to be through CSS. It took a bit of messing around but eventually I worked out how to do this.

For orientations, it was just a case of listening to the onResize event in the main application and then check whether the width was more than the height or visa versa. This would tell me whether the app was in landscape or portrait.

So, in the application's mxml constructor I defined resize function:
resize="resizeHandler(event)"

defined the possible orientation states:

<s:states>
<s:state name="portraitPhone" stategroups="phone,portrait">
<s:state name="landscapePhone" stategroups="landscape,phone">
<s:state name="portraitTablet" stategroups="portrait,tablet">
<s:state name="landscapeTablet" stategroups="landscape,tablet">
</s:state>

and defined the resize handler, which would work out what the orientation and device type was.


protected function resizeHandler(event:ResizeEvent):void
{
var isPortrait:Boolean = height > width;
//determining if its a tablet worked ok with the hardware I tested, but this is not a water tight method.
isTablet = height > 960 || width > 960;

var orientation:String = (isPortrait ? "portrait" : "landscape");
var device:String = (isTablet ? "Tablet" : "Phone");

currentState = orientation + device;
}


Ok, so that's pretty easy.

The CSS in Flex is pretty nifty and can be written in such a way as to change automatically depending on the state of the application. This makes it easy to deal with the orientations. The example I am about to give is not that great. It shows what I am talking about, but once I had it sussed I found out that Form components were not actually mobile ready! Still, the syntax is the same. It's possible to change properties of classes as such:

s|Application:portraitPhone s|FormItem #labelDisplay
{
text-align: left ;
}

s|Application:landscapePhone s|FormItem #labelDisplay
{
text-align: right ;
}


and also the skins of componenets as such:

s|Application:portraitPhone s|FormItem
{
skinClass: ClassReference("spark.skins.spark.StackedFormItemSkin");
}

s|Application:landscapePhone s|FormItem
{
skinClass: ClassReference("spark.skins.spark.FormItemSkin");
}


So, as I was changing the state dependant on orientation in the main Application class, the syntax is:

s|Application:stateName

When the main application changes state the Forms label display should switch from left to right. There was a few more bits of CSS to get the form changing but as I mentioned above, at the moment, you shouldn't be using Forms components in mobile apps, so I won't bother to show the complete example.

Now to get the componenets to update their CSS and redraw at runtime, you will need to add the following line to the end of the resize handler:

styleManager.styleDeclarationsChanged();

I have no idea how fast or slow this is in comparison to other methods people may have, or whether there is a better solution, but the method above seems clean and can be used in conjuction with dpi declarations by nesting them in a @media tag (this is not something I got round to testing mind). It would look something like this:

/* landscape @ 240dpi */
@media (application-dpi: 240) {
s|Application:landscapePhone s|FormItem
{
skinClass: ClassReference("spark.skins.spark.FormItemSkin");
}
}


So, that is the basics of dealing with the different layouts on Flex mobile.

Loading in local HTML files

One thing I wanted to do, as lots of apps will, is to use Google Maps. This is very simple and looks great using native Android programming, but I found that the same is not true in Flex. In fact I would go as far as to say that if you want to use Google Maps in your app then don't use Flex. It sucks.

As the Flash API is now deprecated from Google Maps (and even if you do use it, it won't work on Apple devices), the answer is to use the Javascript API. Hmmmm.... There were a number of things I needed to do such as placing down markers that the user could then move around so i figured I needed some JS functions to achieve this. No problem, I would just use a static HTML page, put all the JS I needed into that and load that into a stageWebView.

Displaying local HTML pages in a Flex mobile app and communicating with it via JavaScript was not as straightforward as I had hoped. After a lot of looking around, experimenting, laughing, crying and cups of tea I ended up using this incredibly useful set of classes called the stageWebViewBridge. The details of this project can be found here:


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


Essentially it simplifies the process of loading in local files and communicating via JavaScript. The wiki entry regarding loading the files was still a bit confusing if using Flash Builder as all the examples are made in Flash CS 5.5 (yes some serious programmer is still using Flash!). The main confusion for myself was working out where to put the HTML files on my machine and how to reference that location from Flash Builder so I will try and clear that up a bit.

When running the app from Flash Builder on a device all you need to do is to create a folder called "www" in the source folder (by default src). This automatically gets copied across to the bin-debug folder by Felx and can then be loaded using:

webView.loadLocalURL("applink:/myHTMLpage.html");


When running using the emulator, things seemed a tad more odd. I had to put the files in:

C:\Users\UserName\AppData\Roaming\LocationAlarm.debug\Local Store\wwwSource

Which got copied across to

C:\Users\UserName\AppData\Roaming\LocationAlarm.debug\Local Store\www

at runtime by the bridge. To load the file was exactly the same as for using a device.

Communication to and from JavaScript was very simple and needs no explanation. Just read the stageWebViewBridge wiki on the link above.

One issue I did have was due to the auto-scaling feature of Flash mobile that I was using. The viewport for the StageWebView needs to have it's size set in pixels. I was using a TabbedViewNavigatorApplication as my main class and wanted the web view to sit inside this. The StageWebView reminds me a bit of the 'directToStage' video in Director (remember that?) in that it sits above all content above the actual application. So, it needs to be the right size. My tabbed navigator was using auto-scaling though, so I had to work out how many pixels big the StageWebView needed to be for the current device. I couldn't find an elegant solution for this but I did find a solution. As discussed here you need to scale it yourself:

http://stackoverflow.com/questions/6759547/air-stagewebview-on-iphone

So, I needed to get the size of the screen inbetween the (scaled) top bar and the (scaled) tabs. This is how I did that:

//firstly get the current scale factor
var currentFlexScalingFactor:Number=FlexGlobals.topLevelApplication.runtimeDPI/FlexGlobals.topLevelApplication.applicationDPI;
//then get the size of the screen minus the scaled sizes of the top bar and the bottom nav buttons
webView.viewPort=new Rectangle(0, systemManager.screen.height*currentFlexScalingFactor-height*currentFlexScalingFactor-FlexGlobals.topLevelApplication.tabbedNavigator.tabBar.height*currentFlexScalingFactor,width*currentFlexScalingFactor,height*currentFlexScalingFactor);

Not very pretty, but it works.
The code to size the viewport needs to be called when the device's orientation changes as well. This will not happen automatically.

So, ultimately I got my map working, but then came across a problem whereby the actual web page would zoom in and out when using pinch/reverse pinch gestures. So the map controls then get massive when zooming in and out, rather than just the map. I found the following "fix" for this. In the HTML page (which I created) just add the following meta tag:

<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">


Simple? Well it would be if it worked. Unfortunately HTC have their own flavour of browser which doesn't support the viewport meta tag. This means that on virtually all HTC devices (I believe there may be one exception) the stageWebView is not a good user experience.

I guess (although am yet to test) that this means HTML based apps will suffer the same problems on HTC devices. If so, they're not an option for commercial apps targeting Android. HTC has distributed way too many devices to be ignored.

Next up was storing data locally. This was easy enough. I ended up using a SQLlite database. This is done the same as it would be in any AIR application. There are great tutorials all over the web on this so I will not bother to explain how this is done.

There is an 'auto-save' type function alos, to save small bits of data when switching between views. Essentially, you just turn it on in the main navigation constructor by setting:

persistNavigatorState="true"


As far as I could tell this is a shortcut to creating shared objects which you save and load using:

//set value
persistenceManager.setProperty("someProp","myProperty");
//get value
persistenceManager.getProperty("someProp");


A more detailed discussion of how this works and other ways of working with it can be found here:

http://devgirl.org/2011/05/18/flex-4-5-mobile-data-handling/

By this point I had come to the conclusion that Flex Mobile was not good at handling any of the 'phone' features that may need to be intergrated. I had a brief look at using Native Libraries to get the phone to vibrate but it isn't a simple procedure. When making a native android app it's two lines of code!

Sunday, 27 March 2011

Nissan Music Mixer

UPDATE: This project won a DMA Gold Award (whatever that's worth)
http://www.dmaawards.org.uk/content/2011gold-best-use-social-media-or-viral












I recently worked on a really interesting project for Nissan, which essentially was to be a live mixing desk. As doing anything 'clever' with sound in Flash is something most people (bar Andre Michelle) steer clear of I was looking forward to seeing how much things had changed since my last sound exploits. Not being a maestro of digital sound/music creation, I knew this was going to be fairly tough assignment but one I was going to learn a lot from.

The brief went something like this. The application would consist of five sound channels each channel being a different component of a song (e.g. drums, bass etc). The channels would be represented by cars (the Nissan angle). Each channel would play one of five loops, each loop being a different genre of music (e.g. funk, ambient, rock) which could be changed by clicking on the car. It was also to be possible to change the volume of each channel by moving the car forward and backward. The idea then was that the user could mix and match genre on the fly, bringing in and out different components of the track to create their own master piece. There needed to be a number of sound effects that could be applied too, such as envelopes, flanges and such like. Once they had a play around, they could then record a mix, which would be uploaded to a server as an MP3. Oh, and they wanted some lighting effects in the background (such as fireworks) and a spectrum analyser! Nothing too much then.

Initially there were a number of technical questions I had, like what the hell is a flange and whether it was even possible to create an MP3 from within Flash! Also, how much control we had over the loops (which were to be made by LaRoux) in regards to length and BPM as I had an idea matching up beats was going to be very difficult, given Flash's slack regard to accurate timing!

So, beat matching... firstly it was decided that the loops should all be the same length and the same BPM as this would make life easier. Naturally there were assets available but luckily one of the guys I was working with was really into his music and knocked up some beats for me. It soon became apparent that Flash's onSoundComplete event is hopelessly inefficient for beat matching as there would always end up being a very small delay between stopping and starting a sound, which was never going to acceptable.

Eventually (with a little help from my very talented friend Kelvin Luck!) I turned to ByteArrays. The solution was to start a single 'empty' sound and add a SampleDataEvent.SAMPLE_DATA event, which would be called everytime the sound buffer was empty. It was then a case of reading the correct samples of each track that was designated to play, alter the volumes of the samples to that which were set, add any sound effect that was on at the time and then write this out to the event data to be outputed as one sound. By doing the mixing in Flash and playing a single sound, things would never get out of synch, which was always the problem playing and changing multiple sounds at the same time.

So first I needed to start the empty sound and listen for the SampleDataEvent.

_sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
_sound.play();

I would store an index for the current sample to read which would be incremented by 4096 (1 second) each time the buffer was empty. When the function was called, I extracted the appropriate samples from each of the tracks that were playing.

//Get index
var n:int = _currentSample + 1 *SAMPLES_PER_EVENT; //SAMPLES_PER_EVENT was set at 4096

//create Vectors for the extracted audio and the volumes
var extractedAudios:Vector. = new Vector.();
var volumes : Vector. = new Vector.();

//and another Vector for the final output
var buffer : Vector.> = new Vector.>();
buffer[0] = new Vector.();
buffer[1] = new Vector.();

for each(var loopId:int in loopIds) {
var playableLoop:PlayableLoop = loops[loopId];

if (playableLoop.isPlaying) {
//store the volume of the track
volumes.push(playableLoop.volume);
//create a new byte array
var sd:ByteArray = new ByteArray();
//get all the samples up to the total samples of the loop
var samplesLoaded:int = playableLoop.sound.extract(sd, SAMPLES_PER_EVENT, _currentSample % _totalSamples);
//get some more samples from the start of the track if the loop got to the end
if (samplesLoaded < SAMPLES_PER_EVENT) {
playableLoop.sound.extract(sd, SAMPLES_PER_EVENT - samplesLoaded, 0);
}
//reset the byte array position
sd.position = 0;
//add the byteArray to the Vector
extractedAudios.push(sd);
}
}



Then I looped through all the extracted samples multiplying the bytes by the volume of the channel and then looped through again, adding the bytes together.


for (; _currentSample < n ; _currentSample++) {
var leftChannel:Number = 0;
var rightChannel:Number = 0;

var index:Number = 0;

for each(var soundData:ByteArray in extractedAudios) {
leftChannel += (soundData.readFloat()*volumes[index]);
rightChannel += (soundData.readFloat()*volumes[index]);
index++;
}
buffer[0].push(leftChannel);
buffer[1].push(rightChannel);
}


This could perhaps be done in the first loop to make it more effecient, but it worked fine so I just left it as such. I needed to add the effects too. I don't have the knowledge required to write sound modulators from scratch so adapted some I found on popforge by Andre Michelle. These took a Number Vector as input and made the mathematical changes for the required effect.

With all that done, I could loop through and write out the byte arrays into the event.


for ( ; i < len ; i++) {
event.data.writeFloat(buffer[0][i]);
event.data.writeFloat(buffer[1][i]);
}


Eh voila, the sound mixing part of the project was done!

The next challenge was to create an MP3 from within Flash. Again, a tricky task indeed, if infact it could be done. After a whole lot of googling and experimenting, it seemed that it was going to be possible to create a WAV from within Flash, and then post that to the backend to be converted into an MP3. I think someone 'may' have written a WAV to MP3 converter in Flash using Alchemy (I vaugely remember seeing something like that), but the client was happy enough with a WAV, which in itself was pretty tricky to do.

Luckily I found a WAVWriter class by Bernard Visscher, which took the samples as a byteArray, adds a header and rewrites the samples so that they are read correctly when played as a WAV. Job done! To test I saved the WAV to the desktop using the FileReference class and it worked great, other than that Flash can't time 30 seconds accurately and the tracks were usually about 36 seconds long using getTimer() in Flash to time 30 seconds! I soon found John Dalziel's Timekeeper class which sorted this out without any dramas.

Is the future of Flash mobile?

Recently I started to get interested in the future of Flash. Given all the Apple fueled hype of HTML 5 I wondered where will Flash be most useful. One massive problem with mobile and tablet development is that when a client wants an application to run on mobile then it has to be remade at great expense on each platform. I would have to find an Objective C developer for the mandatory iPhone version, a Java programmer for the Android version and so on. The images have to be remade and the projects have to managed. Not an ideal scenario...

This is where AIR comes (is coming?) in. I find that mobile apps are often 'addons' to the main web offerings. If the web app is already done in Flash/Flex then it seems like a good idea to create all the other versions in AIR, as most the code is already done.

I had a friend who has a Flash game that he wanted to put onto Android, so I thought this would be the perfect time to have a look at how Flash Mobile is getting on. I downloaded the Flex Hero SDK, the Android SDK and after looking around the web a lot managed to get it all working with FDT. I found a beautie ANT script that will output multiple versions to iPhone, Android and Blackberry Tablet (of which I know nothing about). Anyway I only got to test the Android version on a Galaxy Tab and it worked straight off the bat.

I tried the same project, compiling from Flash CS5 as well, which was super super easy to set up and run.

Also I had a look at Flash Builder Burrito, which has some nice project templates for mobile apps and the Hero components, which are Flex components for use on all mobile platforms to try and keep the interface consistent.

The main downside to using AIR is that it will not run as fast as natively programmed apps and that there is no access to native componenets (sliders, buttons and so on) so the app will not look like a native app.

Juding by what I played around with, it looks like Adobe have really targeted mobile development for the next phase of the future of digital communication and I think there will be real benefits for AIR in the mobile market place.

Friday, 22 October 2010

Unity 3D two day training course




I have just completed a 2 day training course in using Unity3D which I thought would be another string to my bow. I think it's useful to have 'some' knowledge about as many technologies as possible to keep decision making over which technology is best for a job less biased. Given the choice I think people tend to go for what they know rather than what is most appropriate.

Unity3D is an IDE specifically built for creating 3D games. It's cross platform and has exporters for iPhone, Android, standalone (for PC and Mac) and web. Initially it was for first person games only, but in the most recent release it will support third person games as well. This is great, as I did worry about the variety of games that would end up being created. There's only so many ways to skin a cat, and FPS's have been done to death on the console.

So Unity3D is amazing for creating terrains and running around in them. This can be done very quickly with no coding necessary. All the collistion detection can be done very simply too. Shadows are a breeze to create (baked that is... real time shadows didn't really look that great). There is a really good physics engine built in and the whole thing runs really quickly. Yeah, you have to install the plugin, but it's really quick and easy. I don't think that will be a barrier to it's future.

The scripting can be done in c# or javascript. I think the scripting side may seem a bit messy compared to most modern languages, and is a bit reminiscent of the days AS2. Organising which scripts are attached where and referencing other scripts can lead to messy code. I was told that the c# code supports listeners but haven't got round to looking to see if that works the same way as it does in AS.

Here is the game I ended up creating:

Unity3D ROBOT WARS IN THE DESERT!

I was inspired to make some more games, but finding the right models for my ideas may put a stop to me getting too into the whole thing. I like the ability in 2D to be able to quickly knock up images for myself to use which is proving a lot more time consuming in 3D.

Tuesday, 19 October 2010

Sony 3D





I was lucky enough to recently re-make the Sony 3D European flagship site at Tonic.
The site supports around 25 countries, all of which need to able to localise all new and existing content as well as customise the size and style of boxes.

The site was made originally for the US market by a Japanese company, and then hacked by a number of developers so that it had become completely unmaintainable. This wasn't helped by Sony's CMS/asset server set up which really seems to be set up for banners and microsites, as opposed to this pretty huge Flash site.

I was charged with starting from scratch to create a version that could be used going forward. I really had carte blanche to approach it any way I saw fit. After a number of discussions with the Tech Director, we decided to try and remake it in Robot Legs using a very different structure than was there. Also we intergrated the build into Hudson and using Ant, got it building and deploying automatically to a test server.

Code wise it took a while to pull out the useful bits and I had to rewrite most of it.

The final product is about 10x quicker than the original (even quicker than the original Japanese version) and changes that before were taking a week could now be done in a day. All in all a great project to be involved in. It's one of the very few projects I've worked on that makes good use of Papervision and not a carousel in sight!

At the time of writing, the UK version is available to see here:
Sony 3D World

Thursday, 3 June 2010

Childline




One of the latest projects I did was a hi profile job for Saatchi/MovingPictureCompany which was part of a large crosss-media campaign for the NSPCC called How You Feelin?

The project was tied in closely with the TV advert which was a series of clips projected onto buildings of children saying how they felt to a funky beats created by Orbital's Paul Hartnell.

Using a host of videos and sound clips, users piece together a 30 second remix which can then be played back in a fashion which makes it look similar to the original. They can then enter a competition which gives saves their entry and provides them with a url to share if they want to. The winning entry was remade at video quality and aired on MTV.

Php/SQL

I was the only technical guy on the job. As the timeline wasn't too bad I decided not only to do the Flash but to also do the PHP/SQL and to set up the mySql database. I thought it was about time I started branching out and getting some commercial experience in other languages.

The setup was fairly simple, with the Flash app saving to the database using amfphp. The Php also creates a unique url and sends an email to the judges to let them know that a new entry has been entered, with a link to that entry. The user also gets the url once they have saved the entry. Clicking on the unique url would send the user to a seperate page where the Flash would pull in the remix data, again via amfphp, with the users name and the title of the remix displayed. The user could then link back to the original site to make a new remix.

Social Networking

Originally we were then going to allow the users to then share their url directly to Facebook, mySpace, Twitter and Yahoo without leaving Flash, although due to legal reasons related to Childline this functionality was dropped. I did create a service class which did this though so I am hoping a project in the not too near future will ask for similar functionailty as it was pretty tough to make!

I used the new(ish) Adobe networking classes which work in conjunction with Gigya. It was pretty tricky to get it all working though, as each site that I needed to publish too had to be set up on the Gigya site first which in turn created api keys for each of the sites. Any incorrect settings meant that the thing just didn't work! Luckily there are some good instructions on how to do this, although I did struggle occasionaly. Once it was working though it was great. The user would click on the icon of the site they wanted to publish to, a popup would appear asking them to login. Once they clicked the login button the popup would ask for any permissions required to be granted and then close. The item would then be published. The beauty was that once permissions were granted, if the person was already logged into say a Facebook session no popups would be created if they did it again, it just published straight to their wall.

Synching Video and Sound issues

One big issue I had was synching video and audio. Typically there would be around 20 video clips of varying lengths with their own soundtracks, that would play in sync with between none and around 15 audio clips. There was a timeline too, so everything had to look and sound right.
Sounded simple enough. If we have how ever many video clips which last 30 seconds (say 30x1 second clips) and we have say 15x2 second audio clips then everything should be fine. Of course in theory this is ok, but.... I found out along this rocky road that Flash videos would never take the same amount of time to play the same video! That is, creating a little code to trace out the start and end of the video and then set the video to play say 20 times, every time it would take a different amount of time to play! It was never much, around a tenth or two tenths of a second different normally, so generally imperceptably to the human eye, but times this delay by 30 and suddely the video runs over by 3 or more seconds!

After much brain ache and testing, the solution which I used, which worked, was to embed all the videos into swfs and put a silent clip on the timeline under them which I set to synch as Stream. I also embedded all the sounds in swfs, so I could then use frame counting as a way of keeping them in synch rather than timings which never really seem accurate in Flash at the best of times. There was still a problem though as Flash didn't want to drop frames from the video, no matter how loaded the processor got. What I did then, was to count the number of frames passed when the video finished, compared to the number of frames that the video was supposed to have lasted for. I would then skip the first x number of frames of the next clip, thus making everything synch. Admitedly this is not 'the way' to always synch video and could cause problems with very short video clips, typically the video would only overrun by 2 or 3 frames. On a 30 frame clip, skipping the first couple of frames wasn't too bad and ultimately it all synched up.

RobotLegs - MVCS framework

This was my first project using the RobotLegs MVCS framework.
I had been using my own MVC template after trying Cairngorm (boo, hiss) and deciding that frameworks were to bloated, slowed production and actually made sites less maintainable as you had to find someone else who knew the framework to make changes. I went to a talk by Richard Lord at the London Flash User Group, who made a very good presentation on the various new frameworks which gave me the inspiration to go back and take another look at them.

The last point is still valid (on the whole, you still need to find someone who is familiar with the framework to fix and change things), but I have been fully converted and wouldn't start a project now without RobotLegs! It is really lightweight, simple and intuitive. I really liked it and will continue working with it for the foreseable future. Try it out if you haven't already. My own MVC template did start to run into troubles in big projects, but was fine for small/medium projects, although I have dropped it altogether now.