Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2001-507
$eventId
ID of event: wwdc2001
$eventContentId
ID of session without event part: 507
$eventShortId
Shortened ID of event: wwdc01
$year
Year of session: 2001
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC01 • Session 507

QuickTime for Java

Java • 46:37

This session provides a technology overview of QuickTime for Java and covers new features available with the release of QuickTime 5, including support for streaming and Java Wired actions.

Speakers: Michael Hopkins, Jon Summers

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Please welcome Jon Summers, QuickTime Java Engineering. Thank you and welcome to session 507 QuickTime for Java. Now today, we're going to be taking you through some of the new features in QuickTime for Java, specifically those that support QuickTime 5 features. But before we do that, I want to move on to show you, basically, the QuickTime for Java is built of two major components.

QuickTime, which is Apple's proprietary media and Michael Higgins. The architecture is mature, cross-platform, flexible. It has a rich set of services which support industry standard media formats, such as dynamic media, that is audio and video, and a wealth of still image importers and exporters, and also interactive media, such as QuickTime VR and wired sprites. Java from Sun Microsystems is a modern object-oriented interpreted language. You can deploy Java cross-platform as standalone applications, Java applications and applets. So that briefly is the basis of QuickTime for Java. This is what it's built on.

Now, the actual implementation of QuickTime for Java. QuickTime for Java is a cross-platform Java class library accessing the native QuickTime C libraries. It has a core layer, which is an object model that represents the QuickTime C API. This is represented as a set of Java classes which have been grouped into logical packages. Also, QuickTime for Java has a sophisticated application framework of abstracted media services to simplify the integration of QuickTime and Java.

QuickTime for Java delivers on the promise of Java in that it has an identical API across all supported platforms and operating systems. You can write Java applications which use QuickTime for Java on any of the supported applications and deliver that jar to run on all the supported platforms. So in brief, QuickTime Java architecture relies on core services from QuickTime, from Java, and from the operating system.

and the QuickTime for Java 5, which is the version of QuickTime for Java shipping in Apple's current version of QuickTime, that is QuickTime version 5, supports a new, brand new operating system, Mac OS X. with Apple's implementation of Java 2 Standard Edition. As well, QuickTime for Java 5 continues to support classic Mac OS.

with Macintosh Runtime for Java 2.1 and above, and this is based on Java Development Kit 118. QuickTime for Java 5 also continues to support and has enhanced support for Microsoft operating systems, the Windows 95, 98 ME family, and Windows NT and 2000 family operating systems, and require to have installed a Sun-compliant Java runtime edition, 1.1, and also will run with Java 2.

QuickTime for Java 5 has specific enhancements for this new Java 2 environment. There are improvements to the Java 2 security model, and I believe there is a session tomorrow if you're interested in Java security. Specific enhancements in QuickTime for Java have been changes due to issues with garbage collection with the hotspot client compiler.

So QuickTime for Java 5 has new support for the new features in QuickTime 5. Some of the new features in QuickTime 5 is the XML package. QuickTime for Java has an XML parser package which allows you access, and we'll talk about this later. and QuickTime 5 also has a new broadcast API and QuickTime for Java 5 supports QuickTime's broadcast API with the presentation package and Michael will give you a demonstration of that this afternoon. As well, QuickTime for Java 5 has full coverage of the QuickTime 4 API. All of the QuickTime functionality up to and including QuickTime 5 are available through QuickTime for Java. As well, this release of QuickTime for Java 5 has additional functionality and enhanced services.

Now I'd like to go on to a key piece of multimedia presentations, which is time-based multimedia presentations. We can think of a movie time base as having two particular has a rate, which is the rate at which the time base is moving, and also a current time, which is the, for a movie time base, it's the place in time where the playhead is.

QuickTime for Java implements time-based callbacks so that you can receive notification in your QuickTime Your QuickTime for Java application, that is an application written in Java and utilizing QuickTime for Java, You can receive notification of time-based events. As you can see from the diagram, when the playhead reaches a certain time in the movie, you can execute your own Java code. Now, what are these time-based events? They can execute at a certain time, that is, at a certain time within the movie, at intervals. You may want to have a ticker in the movie so that you get notified every second.

and also you can have callbacks which fire at extremes, so you can get notification that your movie has finished. and you can also have callbacks for notification of rate change. That is when the movie starts, when the movie stops, Now, when a movie starts playing, the rate change goes from zero. A rate change of zero means the movie is not playing. To a rate change of one means the movie is moving forward.

at normal play rate. To play the movie backwards, you would change the rate to minus one. Now the reason why I'm going on about time bases is that because they've been reworked in QuickTime for Java 5, they are now much more efficient. and Michael C. Coyne, they are now implemented using high priority native threads for efficiency.

They deliver your Java code executing very close to the time that the callback was actually fired. Also, this rework means that it's and QuickTime callbacks now have an implicit idling mechanism. You no longer have to have a timer tasking thread polling for when these events occur. So now I'd like to move on to the demo to actually show you QuickTime callbacks.

Here we have on 10 a Java application written which utilizes QuickTime for Java. Specifically, this application has been written to have a number of callbacks. The first callback I'll demonstrate is time jumping. As you can see in the console, we can find out where the user scrubs the controller to.

Now we will start the movie and you will notice that we have a rate callback change. I'll just stop the movie. A rate callback change.

[Transcript missing]

Time-based implementation. You'll see the accuracy. We can't measure the latency from the time that the callback is actually called to the time that your Java code executes. We can't measure it on 10.

So we'll restart the movie. And as you can see, we have time-based callback being called once a second. is out of interest. This has a time scale of about 20 million years per second. This is a fluid dynamics simulation of the collision of two galaxies. And if we stop the movie, right goes to zero. Start the movie again.

Now, the movie has stopped and two events have occurred. We have an extremes callback to say that the movie has reached the end of the time base. We also have another rate callback, a rate callback so the movie has stopped, the rate has gone to zero. I think we'll go back to slides now.

[Transcript missing]

Some advice for actually using time-based callbacks is that time-based callbacks require explicit cleanup. That is, on exit you must call cancel and cleanup. Cancel will cancel the callback and cleanup will remove system resources in use. If you want to stop or just reschedule the callback, use cancel. Use the cancel method of time-based class.

For more sophisticated timing services, you should really look at the application framework, where there are some very nice classes, such as the timer class and its target client ticklish objects. And also, if you want to make a presentation which has different elements, which are time-slave, that is, the rate of one object will control the rate of all the other and other media objects within that presentation. The application framework has some very nice services for time-slaving.

Now I'd like to introduce a new feature, an enhancement of the QuickTime VR instance methods in QuickTime Java 5. Specifically, we are supporting the interaction properties of QuickTime VR 5. These new interaction properties deal with panorama mouse click properties. This is the time from when the time or the number of pixels moved before the... and the mouse click gesture becomes an ordinary panning gesture.

That is, the mouse click will time out and the This is a multiplier factor for the pan and tilt. You'll see this quite well in the demo, that basically, if the user is panning across the screen, is using the mouse to pan across a panorama and you change the pan tilt speed, the panorama will speed up or slow down.

Similarly for VR objects, you have a mouse motion scale, which allows you to change the number of pixels the user must move the mouse in order to either rotate the object. And also we have a getter and setter for zoom speed. You can change the zoom speed, which is the zoom in on the Z axis.

For QuickTime VR objects, they have two modes. They have a rotation or translation. That is, normally you can rotate a VR object or you can put it into translation mode so that if it's zoomed in, the The user interaction will be to move that single image rather than rotating the object.

And in QuickTime for Java, We give you access to the two properties, translate on mouse down, which allows you to change the translate or rotate property, the property to either rotate or translate, or the nudge mode. Now, this is similar to the mouse down mode, except it works with the arrow keys. And there we have three states, rotate, translate, or the same as the translate on mouse down. Now I'd like to show you a demonstration of a QuickTime VR with these properties.

Now here we have a QuickTime VR and first of all, the Java application has printed out some information. First of all, we've installed an intercept proc. We've been able to do this with QuickTime for Java 4 and this is one of the powerful things about QuickTime for Java is it's very easy to create great dynamic functionality within a presentation of VR.

We also have another callback, which is the mouseover proc, and this is basically the one where we'll be getting and setting and checking some of these new properties. Now the pan/tilt speed, that is the factor that multiplies the user's interaction with the panorama, is, when we come into the panorama, is set to 5, which is the default. And just for reference, the field of view is almost 40 degrees.

When we enter a hotspot, as you can see, Michael has entered a hotspot before, that the speed would go up to 8. So that if we pan slowly towards this hotspot, when it enters the hotspot, we'll have a notification and we'll increase the speed. and when we leave the hotspot, it will slow back down again. The field of view has not been changed. I'll go back in because I also have another feature More functionality in this demonstration that when we click, we zoom in, and when we leave the hotspot, it reverts to normal.

So here we have a hotspot, this top hotspot number 74, where if we entered the hotspot while panning, the speed would increase again. So we'll do that. As we enter the hotspot, we go past it quite quickly.

[Transcript missing]

I'll just demonstrate that basically I'm going to click in this hotspot and we have a timeout of 30 ticks, half a second. We can change that property. I haven't done this in this particular demonstration.

So here we have another hotspot, and this one will be a very slow hotspot, so we'll pan into it quite quickly. and the user experiences that over that particular hotspot, that's an important hotspot. We've slowed down. Okay, can we return to slides please? Now this sort of functionality is very easy to achieve with QuickTime for Java.

I have some demonstration, some of the source code. This is very simple source code. Basically, We create a QtVR instance using the movie controller and getting the QtVR track from the movie. Then we set a mouse over proc. And the execute function which is an override of the QtVR mouse over hotspot.

Implementation has two actions. Basically it looks at the action selector coming in and when we enter a hotspot, we set the pan/tilt speed to some function of the hotspot ID. This is a very quick demo. Else, when we leave the hotspot, we reset the pan/tilt speed to normal.

Now I'd like to move on and let Michael tell you about the improved support for the Sound Manager. Thank you, Jon. I love having the clicker. Okay, today we're going to talk about some of the new sound manager support in QuickTime for Java 5. This has been greatly enhanced from our previous release to include the additional support of asynchronous recording and playback.

We've also provided the functionality of being able to access the equalizer for the sound channel, so you can get the values of the treble and bass equalizers. And also you can play with level metering, turn that on and off, get the status of that. Now keep in mind that this is the classic sound manager support that is built into QuickTime.

It's not the same as the core audio API, which is native in Mac OS X. There are some other sessions later on in the show. In fact, there are some today and a few tomorrow on that. And that API is accessible from Java. However, since it's X only, we recommend that if you do need to do cross-platform sound development, that you use our sound manager support in QuickTime. Since we've added a whole lot of new functionality, which makes it really nice to use.

So what have we done in the new Sound Manager? We've added an extended scheduled sound header class. This allows you to send buffered sound commands. We've also added an SC status class, and with that you can get the status of the sound channel. You can determine whether it's busy, whether there's a sound playing, and other operations.

We also have an SI completion class that enables you to register a completion routine that will get called upon completion of asynchronous recording, so that your application can be notified when recording is complete, and then save that sound somewhere or play it back to the user. And finally, we've added some additional constants in the sound constants class to expose some of those new constants that weren't previously available. And these include things like new sound commands, as we're going to talk about.

So how do you use the new Sound Manager? And what else have we done? We've enhanced the sound channel class significantly to provide support for doCommand and also doImmediate. The doCommand, when you call that, places a sound command, such as a callback command or a buffer command or a playback command, into the command queue and executes that command immediately. That's the doImmediate call.

Whereas the doCommand will place that command into the queue of commands to be executed by the sound channel. And when the sound channel has executed all its prior queued commands, then it will go ahead and execute that one as well. So the primary difference between doImmediate is that it skips that. Do you want to go ahead and do that? and the Q versus do command, which places the command at the end of the queue.

We also have support for a new callback command, which we'll talk about in detail later, which enables you to get a callback when your command is executed. And we also have some new informational accessors that I alluded to previously, the get level metering on and off, and also a set level metering on and off. So let's look at how you use these in your code.

First thing that we're going to talk about is recording a sampled sound. And these slides are not in full detail. We do have some excellent sound examples as part of the SDK. So if you really want to take a look at this in detail versus this high-level discussion, please go see that. And we'll show you where to download that at the end of our presentation.

So the first thing you need to do to record a sample sound is prepare the sound channel. And the way you do that is you create a new sound input device by calling new SPV device and passing in whatever permissions are appropriate for that type of device. For example, most microphones you can't write to, so you'd want to just do read with that.

Also, you need to allocate a new sound channel and pass the number of channels, the rate, the sample size, and the compression type of the sound that you'll be using. And you can also just retrieve that from the sound input. device if you want, so you can get the defaults for that.

So it's actually pretty easy. Once you've created the sound channel, you create a new sound input parameter block, which you need to pass in that, you need to create the new SPB, pass in the device that you'll be using, and then the buffer size, which is the size that you're going to use for the data, and also the sound handle. You need to pass in where that's going to be stored in the sound handle. Then you can optionally specify a completion proc that will get called upon completion of the recording, and you call that by overwriting the SI completion class and then overwriting the execute method.

So once you've done all that and you want to record the sound, simply call record from your SPB object, and then the sound will start recording. So that's recording. Let's look at playback. To playback the sound asynchronously, which is the more interesting case, you need to prepare a sound command. In this case, we're demonstrating how to use it with the buffer command, which will do asynchronous callback versus the play command, which doesn't.

So you create a new sound command object, specifying the command that you wish to use. And then in the case of a buffer command, you also need to set the buffer that you'll be playing from and give that to command. So you do that by calling setBuffer, and then finally call doCommand on the sound channel, and that will place that buffer command at the end of the queue in the sound channel. If you wish to schedule a callback, you need to create a sound command, excuse me, a callback command, and put that into the channel as well.

But before you do so, when you allocate the sound channel, you specify the sound callback to be used at that time. So a good example of reasons why you'd want to do this is if you need a sound in the background that's going to loop over and over again.

So you could create a sound callback that would be placed on the end of the queue after a sound had been playing. When the play command popped off the queue, your callback command would get fired, and that could put a new sound play or sound buffer. So you could put another command into the queue and also put another callback command onto the queue, and so that would continually loop.

So that's pretty much all there is for playing a sound. When you're using sounds, there are a couple of things that you need to be aware of and cognizant of. And the first is that you need to make sure that you dispose of all your sound channels when you're done playing them.

You can do that by calling disposeQtObject on the sound channel. And if you like, you can do that directly from a callback. It's very important to do that as opposed to waiting for the garbage collector to clean you up because that can be a lot of native data.

Additionally, if you have any completion routines that you've specified and registered with the SPB device, go ahead and remove those as well by calling removeCompletionProc. And finally, there are a couple of garbage collection issues you need to keep in mind. If you have sound objects on the stack, they can go out of scope, so be aware of your use of local variables. SoundManager isn't happy if buffers for sound that's supposed to be playing get garbage collected on you.

Also, make sure that you dispose of all your sound channels when you're done playing them. You can't dispose of any objects that you use within a callback before you dispose of the callback itself. And keeping in mind those guidelines will make sure that your experience using audio is a sound one. Oh, I know that was bad. Couldn't help it. Okay, so now we're going to look at a new area of QuickTime for Java 5, which is the presentation API.

and a bit of an overview first. For those of you that haven't seen any of the previous QuickTime sessions, there was a presentation section. And that showed the new API available with QuickTime 5 that we implemented in QuickTime for Java as well. This enables you to broadcast from any source that is sequence grabber compatible, audio devices such as two turntables and a microphone or any DV audio source, also video devices as well. And you can specify that that broadcast is unicast or multicast, going to a single machine or to a number of machines on the same network. And the broadcast is also user configurable via settings dialog, which we'll see in the demo to follow.

So let's look at how this works from a client side. The broadcaster is a machine that has a set of devices that are connected to the network. It has some sort of device such as a camera connected. And it also specifies, it has an SDP file, which stands for stinky dead pigeon. No, actually it doesn't. It's the stream data protocol.

And that's a standard for specifying how streaming will be sent across the network. And so we use that standard as part of QuickTime since we are a standards based technology. So once you specify the data, you can go to the next slide. So let's look at the broadcast machine.

So the broadcast machine is a machine that is used to configure the SDP file to configure your broadcast. Then those packets are going to go out onto the network and onto any machines which are also viewing the same SDP file. And in this case, the illustration shows that those machines are just using the QT player to open the SDP file. And that doesn't have to be a player. It can be any application that is capable of opening a movie.

So let's look at the broadcaster in more detail now. On that broadcast machine, we have a video system. We have a video camera, which is the source of the broadcast. That goes through the sequence grabber into the sourcer object. We also have a presentation that encapsulates all these various units within the broadcaster.

And the presentation you can think of is kind of like the top level component or a movie that contains all these other objects within it. That's configured by the SDP file, which specifies whether there's audio, whether there's video, whether it's unicast or multicast. What the sample rate is, what the compression type of that broadcast is going to be.

Once that is specified, that's going to affect the packetizer, which is responsible for taking the data from the sourcer object and splitting it up into little packets that it can then send out on the network in an efficient manner. So that packetizer is going to be affected greatly by the compression type that's being used by the sourcer component.

For example, there are packetizers that are specific to Sorenson that know a lot more about its format and can more efficiently send out those packets. And finally, we have the streamer, which is required for actually sending the packets out on the wire. So that's how the presentation works.

and how do we map this into QuickTime for Java? We have a presentation API that's been placed in the QuickTime.streaming package, and we represent that presentation or streaming session by a presentation object. The streaming session is configurable again via settings dialog, which we'll show you in our demo coming up. And we have a streamlined API available now, and we'll be releasing additional features of the API in the future to allow you to do things other than just using the sequence grabber. Oops, skipped a slide, so let's go over to the demo.

And we have a video camera here. It's going to be digitizing all you happy people in the audience. So what I'm going to do first is I'm running a QuickTime for Java applet, and I'm selecting an SDP file, which as I mentioned previously, is simply just a text file.

And at that point then, the settings dialog is going to come up. Let me move that onto the monitor so you can see it. And on the top side you see the settings for the audio, including the component that that's coming from, which is actually in this case coming from the sequence grabber. I'm going to go ahead and edit the sound settings here to, since I don't really care about audio, I'm going to cut that down a little bit.

So that's the component responsible for compression and then on the right side you see the packetizer that's going to use to send that out. And I'm just going to use the QuickTime packetizer. You'll note that it also is recognized that I'm sending an 8-bit sound so there's a special packetizer for that. However, since my .sdp file specified that the packetizer would be QuickTime, I need to make sure that I use the same packetizer. Otherwise the client will be looking for a different packetizer than what's being broadcast and it won't pick that up.

And you can see that I'm using a DV video source. And I'm going to go ahead and turn down the quality a little bit. That's fine. And let's increase the keyframe frequency slightly so we'll actually see some data. And then I'm going to go ahead and hit OK. And we'll look at the broadcast.

So once I click the Start button, you can see now This is what we're digitizing from the camera. And on the other machine, we're going to go ahead now and open the same SDP file up. and the QuickTime player, so you can see what's actually being broadcast across the network. And this is a multicast presentation, and as such, If more than one machine could go ahead and receive that broadcast. And as you can see, we have a little lens flare going on. Somebody in the back waving fiendishly, feverishly, maybe fiendishly as well.

So there we go. We're doing a live broadcast from a DV camera plugged in through a FireWire port from a QuickTime for Java app, all on 10 and being received on a-- Are you receiving that too, Jon? Oh, no, he's just waving. Okay. Anyway, people get so crazy when there are video cameras on them. Alright, so I'm going to go ahead and stop that now and go back to slides.

A live presentation on a Java machine. Can't do that without QuickTime. And that's the beauty of QuickTime for Java. It gives you a very elegant, simplified interface that lets you to do some very powerful features that would take tons and tons and tons of code. We're looking at the code now.

Natively, this would take thousands of lines of code, but in QuickTime for Java, and in the example sent out on the SDK, you'll see that there's really only a couple of lines of code, since we've taken care of a lot of the details for you. You can specify advanced modes, but you're not required to.

So let's look at the presentation API. To create a presentation, you can call presentation from file and specify an SDP file. You can also specify an XML file if you like. And then your presentation parameters, which is an object that lets you specify the sound rate, etc., and data rate.

Then if you like, you need to show your settings dialog by calling new settings dialog and pass in your presentation object. As the note says, and as I previously mentioned, I have to reiterate that the user is responsible, the broadcaster, for choosing a setting that makes sense based on what the SDP file is specifying for the type of broadcast. Since the client that's using that SDP file is only going to look for a specific format of packetizer. And if you choose a different one, well, the client's necessarily... That's not the broadcast I'm looking for, so it won't find it. So make sure you do that correctly.

To prepare and start a presentation, you simply pre-roll your presentation and then call start on it. There's also a callback that you can receive that QuickTime for Java does support that will allow you to determine if the pre-roll has actually occurred. That can be important if you have a slow device that you're grabbing from that just isn't ready yet. Once it's ready, you call start. And to stop, you call stop. It's as easy as it can get.

So, oh, but there is a little bit more. Sorry, forgot. You do have to actually set up an idler. You can create a new task thread that's going to be responsible for calling presentation idle. And that's the mechanism that will go ahead and keep the sequence grabber running and go ahead and actually do all the compression and packetization. And we recommend that you do that in a task thread.

And you can specify in the task thread both a string name, which will allow you to easily recognize it in a debugger, and also a rate of which that thread is going to get serviced. In this case, we chose 20 milliseconds because that seems to be a good value. And then when you override your task method, you just call idle.

And that's really all you need to do to do a live broadcast from any source supported by the sequence grabber in QuickTime for Java. Again, we encourage you to look at the SDK code later if you're interested. And now I'm going to turn the presentation over to Jon Summers again, who's going to talk about transition enhancements. Thank you, Michael. MICHAEL HANSEN: Thank you, Jon.

QuickTime for Java 5 now supports enhanced transitions. To go back, transitions are QuickTime effects. QuickTime effects architecture has a large number of effects that you can apply to still images, that is a single source, and this is represented as a QuickTime filter, a Qt filter in Qt for Java, or it can be applied between multiple sources, a QuickTime transition.

The main enhancement has been to the parameter dialogue. In Qt Java 4, we supported editing and the creation of a QuickTime parameter, QuickTime out of container, which contains the data for a QuickTime effect. And in QuickTime for Java 5, we've extended the parameter dialog so that now you can re-edit the parameters.

This is an important consideration for some of our developers. And as well, we have allowed you to customize the dialog by putting in optional preview pictures. Another new feature of QuickTime for Java 5 is an enhancement to the AtomContainer class, specifically the insertChildCall. We've extended the number of data types to cover all the data types found in QuickTime.

So we have all the simple data types of byte, short, int, and float, and as well, object data types, which will cover all of the other data types that you'll need to actually create QuickTime atom containers. For tween-type atoms, where the data is actually an array of two elements, that is a start and end sample, we have a new class, tweenData, which extends QT byte objects so it can be used directly with the insert child. Call for Adam Container. And how we've constructed, how we've implemented this is to overload the constructor.

So we take We take a start and end value and the types are short int, fixed, float, double, point, fixed point, etc., which are all the types that you will need to create QuickTime tween type atoms. One of the things that we've done for QuickTime for Java and QuickTime for Java 5 is to change the implementation, the semantics of some of the atom container calls.

You'll notice in the insert child we have a parent atom. In some of the QuickTime atom container methods, we have actually changed the semantics so it can actually pass in null, so that actually this will be recognized as being a synonym for atom zero. That is, the container is the parent atom. The parent atom is the container.

and new QuickTime 5 features in QuickTime for Java 5 are support for the XML parser in QuickTime 5. We've implemented this with data classes,

[Transcript missing]

You can get to these elements by creating callbacks, which will be called during the parsing of XML, so you can find out when the document parsing starts, when you reach a particular element. which will allow you to use the QuickTimes XML parser for pretty good XML parsing.

Now I'd like to hand the stage back to Michael Hopkins for more new features. You guys thought we were done. No, we still have plenty of time. Okay, additional new features in QuickTime 5. There's a brand new one that's pretty significant called Drawing Notification Registration. And what that allows you to do is register for notification when drawing and update operations occur on objects such as a compositor, an effects presenter, or a movie presenter. And this actually allows you to do some pretty interesting things. For example, if you aren't really big on using time bases, although that's also an excellent API, you could synchronize a frame rate to the drawing by registering as a listener for a component.

Also, if you need to do some drawing yourself onto an off screen before you present that, you could go ahead and get notification when drawing was completed and then do your additional drawing before that gets rendered to the screen. So the way this works is the listener implements the drawing listener interface and they override the drawing complete method and they can put in any code in there that they wish. You'll also notice that they receive the QT drawable object that generated the message.

Within that call, so you have access to determine its time or what media it's presenting, for example. Once you've overrided that interface, you register your listener with a component by creating a new listener and then adding that drawer listener to the object that you wish to register with. And not shown on the slide, but additionally important, once you're done, you can remove yourself by calling remove drawing listener.

So it's a powerful new feature that we've added, but we're not done yet. We've added a new sizing option in Qt Canvas, a very strange named one called K initial size no resize. And for those of you who are astute Qt Java programmers, you may think, well, there's already a K initial size sizing option. Well, that one allowed an object contained within a canvas within a window to grow smaller but not increase in size. Whereas this new sizing option, absolutely specifies that that canvas will not grow or shrink regardless of what happens to its parent window.

Additionally, we have a new interface called standard Qt constants 5. And oddly enough, this represents newly defined constants in the Qt 5 API. And this supplements previous constants such as the standard Qt constants 4, which represents Qt 4 API, and standard Qt constants, which is Qt 3 and previous. Michael Hopkins, Jon Summers So anything that's in 5 is specifically going to be in that new standard constants 5 interface.

So hopefully at this point nobody's confused. We've added a lot of new functionality in our product. We have a brand new operating system that we're supporting in a very, very high fashion, and that's Mac OS X. We've added new support for compositing, new support for broadcasting, new support for time base.

We've worked through a lot of new features that are part of the 5 API. And as such, you as a developer may have a lot of questions about this, but there are good places to get answers. The first of which is the public mailing list that's available for Qt Java developers. You can go to list.apple.com and sign up for the Qt Java list.

And that's an excellent place for you to go out and get information or ask some questions if you're having difficulty. We highly encourage that because that's a very good community for QuickTime for Java developers. Also, I mentioned previously the Qt Java SDK. We have five new examples in that SDK, and that includes all of the things that we've covered today. So you can get examples for that in that SDK. So that's at developer.apple.com/quicktime/qtjava.

Finally, if you want to be part of our SEED program, I assume everybody's a registered developer here, so if you want to get in on that and get access to prereleases of our software, please send a mail to [email protected]. And we'll get you on that. And we really appreciate your feedback and find out what things are important to you and see how we're doing.

So additionally, I would be shot dead if I didn't plug Bill's book. There's an excellent book called QuickTime for Java Programming. Well, I'm sure all of you are aware of that. It's an excellent book that has a great overview of some of the concepts that QuickTime for Java were built on, as well as a reference in the back. So again, we recommend that.

So at this... Bill, the publisher? The publisher? Morgan and Kaufman. And you can find that on Amazon.com even, I believe. Okay, so I know it's Thursday and a lot of you feel like WWDC is almost over, but there's still a number of excellent sessions coming up. We have the QuickTime feedback forum immediately after this over in J1. It's a good place to come bring your constructive criticism about things in QuickTime you'd like to see.

Additionally, immediately after the session, Jon Berkey is going to give a killer Java graphics demo. That's really important because as QuickTime for Java developers, you will be interacting with things like Swing and the Java 2D API. So those are some good things to do if you want to learn about some of those other ways of rendering in Java. Additionally, we have some excellent audio services class in J2 here at 5 where you can learn about the audio services on Mac OS X.

And there is, as I mentioned, a Java API. So you can call that with Java. And that's a great way if you're a 10 only developer to make use of some really advanced functionality. Additionally, for those of you that are deploying applets, please see Java Security tomorrow at 9. And then of course the Java feedback forum tomorrow at 10:30.