Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is it just me?



I have been programming with Java for a few years now and I
am a SCJP, but I find this QT Java API rather confusing. It just
doesn't seem very Java like to me.

Things that I would expect to be rather simple and intuitive
just aren't. Granted, I just started working with this, but I've
been fighting the API all the way.

insertMedia()
I'm still trying to figure this one out.

10 argument methods
Surely, there has got to be a better way. Is this OOP?

Weak documentation
About the only thing I can find is some JavaDoc and
the examples in the SDK. AFAIK, there is only one
book on the subject and that is almost 3 years old.

Constants
Shouldn't these be capitalized?

Intellisense
For some reason (reflection API?), I'm not getting much
info from the intellisense in my IDE regarding the QTJ methods.
Normally, I would get a get some labels that describe the arguments,
but with this API, I just get something like (int p1, int p2, int p3, int p4, int p5).

Sorry, but I had to get this off my chest.

I'm sure that QTJ is a powerful API and all, but trying to get a grasp
of it from a purely Java perspective seems a bit daunting.

Regards,

No, it's definitely not just you, QTJ is quite difficult to get into, but once you do it's an incredibly versatile and powerful API. I wrote some notes on this a little while ago, and curiously enough I also had a particular problem with insertMedia, so you might find the following useful...

At 22:19 +0200 19/6/01, Rolf Howarth wrote:
After a recent question on the java-dev list, here's a bit of background that I know I would have found useful when I was learning the QT for Java API, starting as I was with plenty of Java but no knowledge at all of QuickTime or the Mac toolbox.

First and foremost, if the QTJava API doesn't seem very Java-like or object-oriented at first glance, then that's probably because it's not (very)! However, that's not necessarily too much of a problem once you find your way around a bit, and once you do you'll find it's a very rich and powerful API.

Why isn't it very Java-like? That's really down to how it works. You're not storing state in Java objects and invoking methods on them to change the objects' state as you would if this was pure Java. Instead, of course, what you're doing is invoking a flat C API to create and manipulate C or Pascal data structures (and opaque ones at that!), using a thin Java wrapper.

If you use a debugger and look at the members of a class such as Movie you won't find a Vector of Tracks that make up the movie, nor indeed any other interesting structures that reveal what's going on. Typically you might find just a single integer. That's all that a movie or similar object is, a *handle* to some underlying QuickTime object. All that most QTJava methods do is a bit of parameter type conversion, invoke a native method, then check the error number that's returned and throw it as an exception if necessary. There are a few data structures and methods that actually do something, but by and large most of the Java classes of themselves are fairly uninteresting.

Most of the functions that relate to particular native structure appear as methods on the corresponding Java object (typically with one fewer argument, as the first parameter is defined implicitly by 'this'). If the native function takes two structures the Java method may appear on one or the other of the corresponding Java objects (or sometimes both!), eg. AddXToY(X,Y) might become either X.addToY(Y) or Y.addX(X).

Typically all the 'big' classes like Movie are descendents of QTObject, which takes care of freeing up the underlying native object once the Java object is garbage collection. However, you can also call a disposeQTObject() method on them to free up memory sooner if you wish.

To use QuickTime for Java undoubtedly you do have to a basic grasp of underlying QuickTime concepts and structures, even if you don't plan to access them directly using the Pascal/C API.

For example, a movie has tracks, a track has media, a media has samples. In a purely Java scenario you might naively expect that to create them you would do something like:

Movie movie = new Movie();
Media media = new Media();
Track track = new Track(media);
media.add(new Sample(data));
movie.add(track);
movie.save(file);
movie.close();

That might be the Java way, but in QuickTime, and hence in QT for Java, you would do something more like the following (this is pseudo-code as I've missed out many of the parameters):

Movie movie = new Movie();
Track track = movie.addTrack();
VideoMedia media = new VideoMedia(track);
media.beginEdits();
media.addSample(data);
media.endEdits();
track.insertMedia();
file.createMovieFile();
OpenMovieFile stream = file.asWrite();
movie.addResource(stream);
stream.close();

Not necessarily too difficult if you have some examples to follow, but not necessarily intuitively obvious either.

For example, I could never understand why Track.insertMedia() takes all manner of arguments *except* a Media! Go figure. Presumably the track already knows about the media and all that insertMedia() is doing is telling it where to put it, but this is hardly clear from the description of the method:

"public void insertMedia(int trackStart,
int mediaTime,
int mediaDuration,
float mediaRate) throws StdQTException

This method inserts a reference to a media segment into a track."

However, paucity of explanation isn't really QTJava's fault, because the original documentation isn't necessarily much clearer either, taken out of context. At least the Javadoc refers you to the original QuickTime documentation. In this example it refers you to the corresponding function InsertMediaIntoTrack:

"The InsertMediaIntoTrack function inserts a reference to a media segment into a track. You specify the segment in the media by providing a starting time and duration. You specify the point in the destination track by providing a time in the track.

pascal OSErr InsertMediaIntoTrack (Track theTrack,
TimeValue trackStart,
TimeValue mediaTime,
TimeValue mediaDuration,
Fixed mediaRate);
etc."

Now, even if that's not much clearer by itself, at least I know where to go to look further as there's a huge amount of documentation on QuickTime itself, available as both PDFs and HTML.

Here are some more Java specific tips and gotchas:

- Remembering that there are underlying native structures helps if you ever need to do 'casts' which aren't allowed in Java but might still make sense in QuickTime. For example, I've sometimes resorted to directly manipulating byte[] arrays and QTHandles when dealing with user data or compression settings.

- When enumerating over tracks in a movie and so on, remember that the original API is Pascal based and indices start at 1, not 0.

- The quicktime.app.* packages contain higher level application utilities, all pure Java, written in terms of the other lower level classes that contain native code. For example, QTCanvas and QTPlayer give you a well behaved AWT component that responds to resizing by a layout manager and an easy way to play movies, but you can achieve the same thing by directly using MovieController, QDGraphics, NativeGraphics, etc.

- Finally, even though QuickTime canvases are heavyweight (peered) AWT components, with a bit of care you CAN combine them successfully with Swing. You won't be able to float other Swing components over the top of a QTCanvas, as it will tend to punch a hole straight through all the layers, but as long as the canvas is on top and you're not overambitious with the control you want over event processing you shouldn't have too many problems.


So, the steps to learning QTJava are first to get a feel for what kind of API it is, and make sure you have access to both the full QuickTime5 documentation and the Javadoc, with working links between them. Only then can you sensibly start looking at examples and tutorials and trying to adapt them to your purposes. You also need to be willing to jump out of the Java world occasionally and look at the C/Pascal documentation when required. That doesn't mean you need to learn the native API as such, but you do sometimes need to refer to its documentation for specific details. Fortunately, the correspondence is generally very close and as in the example above it's easy to see how the description applies to Java.

Don't be put off by any of this. QuickTime itself is a huge and immensely powerful API, and Bill Stewart and the other engineers have done an amazing job at simplifying and making that power accessible from Java. It's a very complete implementation and you get an industrial strength multimedia solution integrated with Java (eg. Java garbage collection, integration with AWT, etc.), with very little performance overhead compared to using it natively. What's more, the same Java code works on Windows and Macintosh, and if Apple ever ported QuickTime to Linux or Solaris you can bet a QTJava implementation wouldn't be far behind!

-Rolf
--
Rolf Howarth, Square Box Systems Ltd, Stratford-upon-Avon UK.




Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.