QuickTime的流媒体API,在Java中由只可在Mac OS(Classic和OS X)中运行的包quicktime.streaming声明。在QTJ中存在Windows版本的类,但是它们却不能工作。
作者:builder.com.cn 2007年8月24日
关键字:
创建Presentation
我们的流媒体服务器程序调用LittleBroadcast,这并没有多少代码,只有不过140行。在本文中,我将一步一步的进行,解释一般的部分,但提供其全部的清单。在后面的Resources章节中有可用到一个.tar.gz文件,连同SDP文件和一个Ant构建文件。
package com.mac.invalidname.qtjstreaming;import quicktime.*;
import quicktime.std.*;
import quicktime.util.*;
import quicktime.qd.*;
import quicktime.io.*;
import quicktime.streaming.*;
import quicktime.app.time.*;
import java.io.*;import java.awt.*;
import java.awt.event.*;
public class LittleBroadcast extends Tasking implements ActionListener {
这是一长串典型的引入QuickTime,包括了使用其QDGraphics来提供一个摄像机画面以外的图形界面的qd,读取SDP文件的io,用于流媒体API的streaming,以及获得给予Presentation运行时间的有效任务的time。最后一点,注意该类扩展直Tasking――提供周期性调用的task()。本应用程序中,它用于不断的调用Presentation的idle()方法,并使其循环工作。你在本书中学习到也就是Movies所需要的,但是此任务几乎一直都自动的为你所操作。使用Presentation并不好运。(或者为此事而捕获,但有些离开本主题了。)
boolean broadcasting = false; public static final int BROADCAST_WIDTH = 176; public static final int BROADCAST_HEIGHT = 144; Button startStopButton; Button configButton; Presentation pres; int presenterTimeScale = 600;
这些是服务器的实例变量。是一个用于指定当开始/停止按钮按下的时候做什么的标记。下面是一对广播视频大小的常量,紧跟着是服务器GUI的按钮。最后是一个Presentation对象,以及它的时间尺度。(媒体的保持时间系统,一个600的时间尺度表示一秒种里有600个单位;600也是QuickTime中默认的。)
public static void main (String[] args) {
System.out.println ("main");
try {
QTSession.open();
new LittleBroadcast();
} catch (QTException qte) {
qte.printStackTrace();
}
}
在这个main中并没有什么独特的地方。我投入了所有的精力在构造函数上以防止为那些我需要的实例创建一个内部类。如果你扩展本代码,你可能会发现这很有用。
public LittleBroadcast() throws QTException {
System.out.println ("LittleBroadcast constructor");
QTFile file = new QTFile (new File ("little.sdp"));
try {
MediaParams mediaParams = new MediaParams();
mediaParams.setWidth (BROADCAST_WIDTH);
mediaParams.setHeight (BROADCAST_HEIGHT);
QDGraphics myGWorld =
new QDGraphics (new QDRect (
BROADCAST_WIDTH, BROADCAST_HEIGHT));
mediaParams.setGWorld (myGWorld);
PresParams presParams =
new PresParams( presenterTimeScale,
QTSConstants.kQTSSendMediaFlag |
QTSConstants.kQTSAutoModeFlag |
QTSConstants.kQTSDontShowStatusFlag,
mediaParams );
pres = Presentation.fromFile(file, presParams );
构造函数的第一事是装载名为little.sdp的SDP文件。 但这并不是所有的都需要创建Presentation ――在调用Presentation.fromFile()的时候需要服务器应用程序设置一些必要的参数。首先,你要创建一个MediaParams对象,这样你能设置视频的高度和宽度。您必须做的其它重要事是提供照相机一个图形界面,由QDGraphics创建MediaParams设置。是的, 名字是古怪的, 因为QTJ 设计员想注重与AWT Graphics对象的相似性, 但得到或设置这样的对象的用途的所有方法是使用其本地API名字, GWorld。 最后, 你为所有的Presentation创建一个PresParams来设置参数。 这采取一个有些任意的时标, 一些算术上的行为标记彼此OR'ed, 以及MediaParams。 可能的行为标记, 都被定义在QTSConstants, 包括:
·KQTSAutoModeFlag: 都使用默认值。 最重要地, 这些使用默认值Sourcer, Presentation的来源,是从各种各样的输入装置执行获取的SequenceGrabber。 它还可能播放一个在磁盘上或是任意目录下的的QuickTime 文件; 稍后我将探讨这些问题。
·KQTDontShowStatusFlag: 不要创建一个会导致连接数和状态信息总被显示在客户端的流媒体状态处理程序。
·KQTSSendMediaFlag:发送,不接收数据。
·KQTSReceiveMediaFlag:接收,不发送数据。
在SDP文件说明, 参数, 以及GWorld 设置下, 创建Presentation和Presentation.fromFile()。
// find audio stream Stream audioStream = null;
for (int i=1; i<=pres.getNumStreams(); i++) {
System.out.println ("stream: " + i + ": " +
pres.getIndStream(i));
Stream aStream = pres.getIndStream (i);
if (pres.hasCharacteristic(aStream,
StdQTConstants.audioMediaCharacteristic)) {
audioStream = aStream;
break;
}
}
System.out.println ("audioStream = " + audioStream);
pres.setVolumes (audioStream, 100, 100);
System.out.println ("created presentation, gworld == " +
pres.getGWorld() + ", size == "+
mediaParams.getWidth() + "x" +
mediaParams.getHeight() + ", streams == " +
pres.getNumStreams());
//*******这不是真正地必要的, 但它将告诉你怎么通过Presentation游览来挑选各自的流媒体。 Presentation.getIndStream 会由索引返回一个Stream(附注QuickTime 索引都是基于1)。它重复这些audioMediaCharacteristic 请求查找音频流 (对于录影, 您就要请求visualMediaCharacteristic) 。 这个实例在audioStream上为左右声道设置音量最大值为100。
最后, println从Presentation和MediaParams转存一些有意义的元数据。