Development is not limited to just Web applications, Web services and the
like; right? So this time around we decided to take up something that you might
encounter while developing the not-so-typical applications. Or, they might even
be a bit typical ones. QT is used widely in Web sites for displaying multi-media
content. And much to your liking; they a have a whole collection of APIs in
different languages for programmatically adding QT player to your application or
Web page. In this article we will look into the Java based APIs for QT
development. We will make an applet that displays movie text for a QT movie.
|
QuickTime for Java
Well as the name suggests 'QT for Java' provides the framework for developing
Java applications with rich QT media capabilities. Using this, you can do
anything that QT allows including (but not limited to) editing, creating movies,
capturing audios/videos and 2D/3D animations. The framework consists of two
layers. The Core layer provides access to the QT programming API. The second
layer integrates QuickTime APIs and Java. For example, capabilities like sharing
events between QT and Java etc. This layer also simplifies the usage of
QuickTime API that is written in native code by providing a logical
transformation of the native method calls to Java method calls. This helps
developers in many ways. For example; using the API in this layer, reduces
overheads associated with making native method calls directly (without using
these APIs) such as parameter marshalling/de-marshalling, and checking for error
conditions to name a few. In case there is an error, relevant exceptions are
thrown by this layer. For details on the API reference and API docs, you can
visit the URL
http://developer.apple.com/quicktime.
Setup
You need to do a custom setup of QT player. Choose the custom install option and
go for the 'Quick Time for Java' option. Plus you need a JVM, which should be
version 1.1 or higher. Additionally, you can also download the QT for Java SDK.
We downloaded and extracted the version 6.1 for the SDK. You just need to Unzip
the compressed file to any location of your choice on the hard disk to complete
the SDK setup.
Adding movie text
Here's how to go about adding movie text using QT for Java. Our application
opens a dialog box allowing user to select a QT movie and then adds the text
“This from the API's” to this movie. Here is how to start off with the code.
public class PCQMText extends Frame {
public static void main (String args<>) {
new PCQMText();
}
public PCQMText() {
try {
QTSession.open();
QTFile qtf = null;
try {
qtf = QTFile.standardGetFilePreview
(QTFile.kStandardQTFileTypes);
} catch
(quicktime.io.QTIOException e) {
if (e.errorCode() != Errors.userCanceledErr)
e.printStackTrace();
else
System.out.println ("Quitting....");
QTSession.close();
System.exit(1);
}
We use QuickTime Session and QuickTime File objects initially. The former
basically checks if QT is present. If found, it calls for the static 'enterMovies()'
method that ultimately results in a call to the native method
QuickTime::EnterMovies. These calls are accumulative i.e. for every opening of a
QT Session by a call to QTSession.open(), which calls the QTSession.initialize()
method, there should be a QTSession.close() method (which calls the
QTSession.terminate() method. Alternately, the same applies to using
QTSEssion.initialize() or QTSession.terminate() methods, if used directly. We
then open a QT file through a file open dialog. Next steps are to obtain the
path of the file and perform some basic editing. The editing in our case is
adding the text we mentioned a little while ago. To do so, we obtain a reference
to the QT movie opened into a new 'Movie' object and then extract the movies
properties such as height, width etc. This is how it is done.
DataRef urlMovie = new DataRef ("file://" +
qtf.getPath());
Movie m = Movie.fromDataRef (urlMovie,StdQTConstants.newMovieActive);
float textTrackHeight = 48;
QDRect movieBounds = m.getNaturalBoundsRect();
float movieWidth = movieBounds.getWidthF();
float movieHeight = movieBounds.getHeightF();
Once the basic properties are extracted we create a new movie track that
spans the width of the movie selected using the 'Track' class and then position
this track along the bottom of our movie. Finally, the text track is enabled.
Track textTrack = m.addTrack (movieWidth,
textTrackHeight, 0);
Matrix textTrackMatrix = textTrack.getMatrix();
textTrackMatrix.translate (0, movieHeight - textTrackHeight);
textTrack.setMatrix (textTrackMatrix);
textTrack.setEnabled (true);
The last parameter in the call to addTrack() method is for volume. The zero
value indicates no sound. The 'Matrix' class like any matrix in graphics
operations defines the mapping of points from one coordinate space to another.
The following few steps extract further the time scale of the selected movie and
then initialize a 'TextMedia' object that represent the movie text to be added
in QT movie.
int movieTimeScale = m.getTimeScale();
TextMedia textMedia = new TextMedia (textTrack, movieTimeScale);
QDRect textBounds = new QDRect (movieWidth, movieHeight);
The editing now begins by first sampling the time duration and then creating
a String object with the text that has to be added to the movie. The String
object is then used to initialize a QTPointer object that is a pointer to be
used in calls to a QT movie.
textMedia.beginEdits();
TimeInfo sampleTime = new TimeInfo (0, m.getDuration());
String text = new String ("This is from the API's for Java!");
TextMediaHandler textMediaHandler = textMedia.getTextHandler();
QTPointer textPointer = new QTPointer ( text.length() + 1, true );
The Boolean parameter is for specifying whether to clear the pointer on
creation or not. True indicates clearing the pointer on creation. Next, we
transform our Java string to a 'C' style string for QT
textPointer.copyFromArray ( 0,
text.getBytes(), 0, text.length() );
textMediaHandler.addTextSample (textPointer,QDFont.getFNum("Times"),20,0,QDColor.Yellow,
QDColor.white,QDConstants.teCenter,textBounds,StdQTConstants.dfClipToTextBox |
StdQTConstants.dfKeyedText,0,0,0,null,sampleTime.duration );
textMedia.endEdits();
The endEdits() method closes the editing part of our applet. Next, we insert
the media, write the edited movie object to the QT file and close the sessions
to end our exercise.
textTrack.insertMedia (sampleTime.time, 0,
sampleTime.duration, 1 );
OpenMovieFile outStream = OpenMovieFile.asWrite (qtf);
m.updateResource (outStream, StdQTConstants.movieInDataForkResID, qtf.getName());
} catch (QTException e) {
e.printStackTrace();
QTSession.close();
System.exit(0);
}
QTSession.close();
System.out.println ("Done.");
System.exit(0);
}
That's all for adding a movie text to a QT movie. Of course, you can do a lot
more editing to QT movies using these libraries or APIs, but we took a trivial
example for simplicity sake. So, once you are done with the samples in the QT
for Java SDK and have a grip on what these classes are for, go ahead and play
around with the movies using these relatively easy to use APIs than the native
libraries for becoming a programmatic movie editor.