Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Thursday, August 09, 2007

Flash Quicktime Controller : Quicktime API

In the last two posts I've been looking at communication between Flex and Javascript using ExternalInterface. With the final goal being to create a Flex controller for a Quicktime movie (why?). In this post we'll take a look at the Quicktime API and some examples of how we would use it to communicate with Flex.

The Quicktime API is broken down into 4 sections :
  • Movie Commands
  • Quicktime Properties
  • Movie Properties
  • Track Properties
We'll be working with the first three of these sections. As mentioned in the last post we get Flex to call a javascript function to load the Quicktime movie once the Flex application has finished loading. I'm adding the Quicktime to the page using AC_Quicktime.js (instructions and code). This script has a function named QT_GenerateOBJECTText_XHTML that returns the required string for the embed which I add using innerHTML:
function qt_add(src)
{
var str = QT_GenerateOBJECTText_XHTML(src,'320','240',
'',
'autoplay','true',
'name','qt_mov',
'id','qt_mov',
'controller','false',
'emb#bgcolor','black',
'align','middle');

var o = document.getElementById('qt');
o.innerHTML = str;

interval_ID = window.setInterval("qt_Status()",100);
}

The Quicktime movie needs to load completely before we can inform Flex of the movies duration and current position. To do this we need to use GetPluginStatus(). This function returns a string with one of five possible values (Waiting, Loading, Playing, Complete, Error). By using javascripts setInterval method we can regularly poll the Quicktime movie to check it's status. Once it's status changes to "Complete" we can end the polling and inform Flex that the Quicktime movie is ready. The code to check the load status looks like this (assuming a Quicktime movie with an ID of "qt_mov"):
var s = document.qt_mov.GetPluginStatus();

if(s == "Complete")
{
window.clearInterval(interval_ID);
//tell Flex app movies length
get_qt_duration();
}
I'm going to tell Flex that the movie has loaded by sending it the movies duration (in milliseconds) using the GetDuration method. Within Flex this value is used to set the HSliders maximum value :
 function get_qt_duration()
{
var d = document.qt_mov.GetDuration();

var o = document.getElementById('QT_SWF');
o.set_qt_duration(d);
}
You'll also notice in the status script that we setup another setInterval to regularly check the position of the movies playhead. We can get the time elapsed using GetTime. Within Flex we use this to set the HSliders value.
 function set_qt_time()
{
var d = document.qt_mov.GetTime();

var o = document.getElementById('QT_SWF');
o.set_qt_time(d);
}
Thats really all the information I need to send from the Quicktime movie to Flex. There is of course a few things I'd like to be able to do from Flex. Lets start with the basics ; I want a button to Play/Pause the movie. I don't want to go into the mechanics of the Flex side as I'm assuming that this is a common enough process. But in javascript I decided to go with a function to start and a function to stop the Quicktime movie:
 function qt_play()
{
document.qt_mov.Play();
play_state = true;
}

function qt_stop()
{
document.qt_mov.Stop();
play_state = false;
}
It really doesn't get any simpler than methods called Play and Stop. The next thing we want to be able to do is drag the slider in Flex and then update the Quicktime movies position. We can do this using the setTime method. But there is a small problem. Setting the movies position stops the movie. So you need to follow setTime with a Play() command. But in our example we won't want it to play if the movie is paused. Hence the play_state variable in the last two functions. Now we only restart the movie if the play_state is true :
function update_qt_time(t)
{
document.qt_mov.SetTime(t);

if(play_state)
{
document.qt_mov.Play();
}
}

In Flex we are listening to the sliders thumbPress and thumbRelease events. I respond to the thumbPress by setting a variable called slider_drag_state to true. This is because I don't want the slider to update while I'm dragging it. On thumbRelease we call the javascript function update_qt_time with the new slider value and the Quicktime movies position is updated.

There is a lot more we could do with our Quicktime controller. But this is just a very basic proof of concept to check what is and isn't possible before moving onto the real application later in the year.

Wednesday, August 08, 2007

Flash Quicktime Controller : Javascript To Flex

In my last post we started looking at creating a Flex controller for a Quicktime movie. Specifically we looked at calling javascript functions from Flex using ExternalInterface. This time we'll talk about calling Flex functions from javascript.

As you may remember we called a javascript function after the Flex creationComplete event is fired so the Quicktime movie doesn't load until after the Flex application. Next we'd like to tell the Flex controller that the Quicktime movie is loaded. I'm not going to talk about the Quicktime API in this post so lets assume that there is a mechanism for testing the load state of the Quicktime movie. We have a javascript funtion qt_status which is listening for the Quicktime movie to finish loading. When the load is complete we want it to call a Flex function. For this to work we need to register this event within Flex before it's needed by the javascript function. Once again we'll use the creationComplete event (i.e before we load the Quicktime movie) to register the available functions.
ExternalInterface.addCallback("qt_complete", qt_complete);
As you can see we use ExternalInterface addCallback and send it a string representing the function name to call from javascript (can be different from the actual function name) and the actual Flex function name this refers to. As discussed in the previous post you need to check for the availability of ExternalInterface before adding this callback. Once created you can call this function using javascript, adding parameters if required , like this :
var myFlexApp = document.getElementById('QT_SWF');
myFlexApp.qt_complete(myParam);
For this to work the Flex applications ID needs to be set to 'QT_SWF'. With this done it's really simple to get javascript to communicate with your Flex application. In the next post we'll look at the Quicktime API and using it to interact with our controller.

Tuesday, August 07, 2007

Flash Quicktime Controller : Flex To Javascript

For the last few days I've been prototyping a Flex controller for use with Quicktime movies. The prototype is for an upcoming project that needs to interact with videos from a number of systems. At least one of those systems doesn't publish to Flash.

I'm going to talk about this over a few posts. In this first post we'll look at calling javascript functions from Flex.

In the end I used a HSlider component to create the scrubber and then added a Button to play/pause the movie. The interaction was handled by ExternalInterface on the Flex side and within the page javascript was used to communicate with the Quicktime plugin using it's API.

ExternalInterface is extremely easy to use. You simply need to pass the javascript functions name to the call method:

ExternalInterface.call("functionName");

You can also add parameters (required by the js function) after the function name. ExternalInterface isn't available in all browsers so you should wrap this call in a conditional to check if ExternalInterface is available :

if (ExternalInterface.available)
{
ExternalInterface.call("functionName");
}

Now all you need is a javascript function in your page to respond to this call. In my prototype
I don't want Quicktime to load until after the Flex app has loaded. So I created a js function called swf_init that is called after Flex's creationComplete event. This function adds the Quicktime movie to the page. In the next post I'll talk about creating callbacks with ExternalInterface so javascript functions can talk to our Flex app.