Windows ANE for native dialogs

My post on creating native alerts with Adobe AIR has proven to be quite popuplar so I decided to follow it up with something even better (at least for Windows apps).

Recently I have been dabbling in a bit of C# for creating Windows Store apps as well as some C/C++ to try and figure out how to create Native Extensions (ANE) for Adobe AIR. As a first ANE I decided to make a native dialog extension. Extensions for this already exist for iOS and Android but I was unable to find any for Windows.

READ MORE

Converting video with FFmpeg and Adobe AIR

Something I have been wanting to do for a while now is build a video converter into my Module Builder to enable automatic conversion of video into the various web friendly formats but I could never find a way to do it.

Over the weekend I discovered this tutorial on playing back any video in Adobe AIR. The tutorial runs through how to set up a NativeProcess to hook into FFmpeg to stream video from any format into FLV. FFmpeg is an open source media library for playback and conversion of almost any type of video or audio and is used by VLC and many other applications. I finally had a possible way of converting video within an AIR app! And one of the great things about this is since its using the NativeProcess API the conversion works asynchronously and the app doesn’t lock up while its converting.

READ MORE

Uploading video from iPad to server with AIR for iOS

In this part 2 post following on from Record and play back video with AIR for iOS on iPad I will show you how to take your freshly recorded video and upload it to a web server using PHP.

Assuming you have a MovieClip or some other button labeled ‘uploadbtn’ you first need to add a click event handler to it to trigger the upload.

1
uploadbtn.addEventListener(MouseEvent.CLICK, onUpload);

Now for the click handler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function onUpload(e:MouseEvent):void
{
    // create a URLRequest for the PHP file on you server (we'll get to the PHP later)
    var URLrequest:URLRequest = new URLRequest("http://www.yourdomain.com/uploadFile.php");
   
    // videoFile is a File object we created in the last post which references the recorded video
    // attach the various listeners for errors, progress, complete
    videoFile.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadDataComplete);
    videoFile.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    videoFile.addEventListener(IOErrorEvent.IO_ERROR, handleError);
    videoFile.addEventListener(Event.COMPLETE, completeHandler);
   
    // call upload on the File object and pass in the URLRequest
    videoFile.upload(URLrequest);
}

Now we can create the handlers for the attached listeners:

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
function progressHandler(e:ProgressEvent):void
{
    // just tracing the percentage of progress - you could show it in a progress bar
    trace("Uploading... " + Math.ceil(100 * (e.bytesLoaded / e.bytesTotal)) + "%");
}

function completeHandler(e:Event):void
{
    // upload process is complete
    trace(videoFile.name + " has been uploaded.\n");
}

function uploadDataComplete(e:DataEvent):void
{
    //everything is complete, trace the message returned from the PHP script which is in XML format
    var xml:XML = new XML(e.data);
   
    trace(xml.message);
}



function handleError(e:IOErrorEvent):void
{
    // simple error handler traces the error
    trace("Upload Error:" + e.text);
}

That is all that is required for the ActionScript side of things. Now for the PHP script. This is a very basic script and you should provide some security and validation on any production code.

All you need to do is save this into a blank PHP file and upload it to your server to the location matching the address in you URLRequest above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

// variable for return message
$message = "";

// the directory to place the video relative to this PHP script
$directory = "uploads/";

// get the number of files already in the directory and increment the number for the new one
// video from the iPad is always .MOV format
$fileCount = count (glob ($directory."*.MOV"));
$newName = $directory."video" . ( $fileCount + 1) . ".MOV";

// move uploaded file with new name into directory specified above
if (move_uploaded_file($_FILES["Filedata"]["tmp_name"], $newName)){
    // create a successful message if all went ok
    $message =  "<result><status>OK</status><message>$file_name uploaded successfully.</message></result>";
}else{
    // create a failed message if something went wrong
    $message =  "<result><status>FAIL</status><message>$file_name did not upload successfully.</message></result>";
}

echo $message;
?>

That is all that’s required to upload a video from the iPad to a web server. It is surprisingly simple for how hard it was for me to work out.

I hope this helps somebody out!

Record and play back video with AIR for iOS on iPad

Recently I needed to figure out how to create an iPad app when you can record and play back video from the iPad’s camera, and then upload to it to a server using AIR for iOS. I wasn’t able to find a whole lot of info on it and so I eventually pieced it together from various places. I decided to share the first part of the process here, and I might share the second part in another post later.

I will assume you have a button on the Flash stage called ‘recordbtn’ which the code below will use to fire up the device’s camera.

First we have to set up some variables and check for StageVideo availability:

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
// use stage video to playback recording
var stageVid:StageVideo;

// variables for displaying the video
var videoFile:File;
var ns:NetStream;
var nc:NetConnection;

// create instance of CameraUI for showing native camera app
var deviceCameraApp = new CameraUI();

// we'll use StageVideo to display the recorded video, first we have to listen for availability
stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoAvailability);


function onStageVideoAvailability(e:StageVideoAvailabilityEvent):void
{
    // if StageVideo available
    if (e.availability == StageVideoAvailability.AVAILABLE)
    {
        // get stage video instance
        stageVid = stage.stageVideos[0];

        // create a net connection for playing back the video
        nc = new NetConnection();
        nc.connect(null);
       
        // create a netstream for the net connection       
        ns = new NetStream(nc);
        ns.client = this;
       
        // add click event to record button
        recordbtn.addEventListener(MouseEvent.CLICK, onRecord);
       
        // add event for stage video render state
        stageVid.addEventListener(StageVideoEvent.RENDER_STATE, onRender);
    }
   
}

function onRender(e:StageVideoEvent):void
{
    // when the video is ready to play set the viewport size so we can see the video
    stageVid.viewPort = new Rectangle( 247 , 43 , 529 , 397 ) ;
}

READ MORE

Emailing images directly from Flash with PHP

For an interactive drawing project I worked on recently I needed to provide the ability for users to email their artwork directly from the app without the need to save any images to a server. I pieced together a solution from various blogs and websites and I decided to provide the full source here.

The function below takes an encoded bitmapdata and an email address and sends them to the PHP script further down in this post. The bytearray passed in must be encoded as a JPG – you can use any of the available encoders such as CoreLib, Faster JPG Encoder, or the Alchemy Encoder.

READ MORE

Adding console.log() to AIR’s HTMLLoader

Here is a little code snipped I thought I’d post for future reference and may help someone else out.

I was using the HTMLLoader class in Adobe AIR to load content and I came across an error where my Javascript was calling console.log(). In the AIR HTMLLoader environment this function does not exist so I had to come up with a way for it to stop throwing errors.

The solution I came up with was to create the console object and add the log function. That way I could trace out any log info or do anything else with it if I need to. So here is the snipped to add console.log to the HTMLLoader.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* creating the loader object */
var ldr:HTMLLoader = new HTMLLoader();
ldr.load(new URLRequest('path/to/html/file.html'));
ldr.addEventListener(Event.COMPLETE, onLoaded);
addChild(ldr);

/* when load is complete, do the magic */
function onLoaded(e:Event):void
{
    /* Create console object on the window */
    ldr.window.console = {};
    /* add the log function to the console object, this function could do anything with the log data but here I am just tracing it */
    ldr.window.console.log = function(msg){trace(msg)};
   
}

Easy.

Combining PixelBender paint mixing with TUIO blob size

This post has been sitting around in draft for a while now so thought I’d better publish it. I finally got around to recording a video demo of an app I’ve been working on for a client. I needed to combine my PixelBender paint mixing with blob size so that the brush is the size of the object touching the screen. The video below demonstrates the app using TUIO and CCV. The final version will most likely be using GestureWorks and an Iduem screen.

A simple way to get native alerts with Adobe AIR

In an AIR project I am currently working on I wanted to have native alert boxes in my app rather than building custom pop up boxes. There is no built in way to get native alerts in AIR and I remembered reading this interview over at leebrimelow.com a while back where a developer at Illume used StageWebView to trigger an alert from a HTML page. So I decided to make a class called NativeAlert that uses AIR’s HTMLLoader to trigger alerts.

READ MORE

New Showreel!

I have just uploaded my new showreel to Vimeo. A couple weeks ago I was listening to TripleJ in the car and I heard this amazingly bizarre, vintage, sci-fi, horror metal song come on. Unfortunately I missed what it was called or who the artist was so I spent ages trying to figure it out. READ MORE

PixelPerfect digital art wall

Update: It has come to my attention that some companies have been claiming that Classy Event Group is just a software reseller for Virtual Graffiti Wall. This is entirely untrue. I have worked with Classy Event Group to design and develop this software for them. Classy Event Group is the sole owner of this software and it is not available anywhere else.

PixelPerfect is a digital art wall app I built for Classy Event Group using Adobe AIR. After seeing a video I posted over at the  NUI Group forums they asked me to build a customised version of my stenciling and painting app for their digital art wall. PixelPerfect uses a new stencilling method which I developed which is not only heaps faster, it also leaves paint on the stencils – something which we hadn’t seen before in previous stencil applications. The app has the ability to load in background images and transparent foreground images and the saving and printing of creations. The service provided by Classy Events Group also enables a photobooth function. The app watches a folder for photos and a DSLR saves images to the folder enabling the user to instantly pull up their photo and draw on it.

READ MORE