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.

8 comments:

VerlSnake said...

Hello GeekGlue !

I am researching the following topic: "Accessing QT movie track variables/handlers from JS"; since Your blog entry deals with communication of JavaScript to QuickTime, I allow myself to post these questions as a comment:
- I want to access already created sprite track variables and custom event handlers not only from within QT, but also from the outside; from the embedding web page
- I know that I can access sprite track variables from the embedding web page via JavaScript
- But how to access custom event handlers from the embedding web page ?
- If I cannot access those custom event handlers DIRECTLY: Is there a mechanism inside QT which allows me to call those custom event handlers when a sprite track variable changes its value ? A kind of sprite track variable observer/listener ?
- I have read somewhere that QuickTime 7.3 has enhanced its JavaScript API. Where is the description of the latest QuickTime 7.3 JavaScript API which perhaps offers this capability in a seamless manner ?

TIA for Your answers

Kai

geekglue said...

Thanks for the comment Verisnake. I'd like to say I knew the answer to your questions. But it's outside the scope of my own research. In fact, a fair part of my interest in Flex is that support for extending Quicktime is too hard to come by.

Close said...

Could this be what you're looking for?

geekglue said...

Hi close,

thanks for posting the link to the newly updated Javascript Scripting Guide for Quicktime. I think the additions to the guide will greatly help. But I was also referring to the absence of a substantial support community around Quicktime development.

Close said...

You're right, there's no community whatsoever, and the support is very limited. I wish it would be like the Webkit community...

vinod said...

i have developed a video player in flex.Now i want to communicate the Quicktime API.Can you explain step by step procedure so that it will be helpful to me

Anaya Labs said...

Great post!
Can you please let me know if AIR supports quicktime runtime?

geekglue said...

AIR doesn't have any specific QT support to my knowledge. So it would be in the same position as any other application or plugin available on the machine. I don't have any experience with this myself.