These files have been updated for use with
Savant. That is, org.thdl.savant.SoundPanel has been eliminated in favour of these classes, which are shared between QD and Savant. The main change is that SmartMoviePanels can now communicate with the outside world, for example to send messages to a Savant text window telling it to update highlights.
This commit is contained in:
parent
da9a576e02
commit
392b2b180a
4 changed files with 394 additions and 254 deletions
|
@ -30,8 +30,6 @@ import org.thdl.util.ThdlDebug;
|
|||
/*-----------------------------------------------------------------------*/
|
||||
public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListener
|
||||
{
|
||||
private EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
public URL mediaURL;
|
||||
|
||||
private Player player = null;
|
||||
|
@ -54,9 +52,12 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
|||
|
||||
private Float to = null;
|
||||
/*-----------------------------------------------------------------------*/
|
||||
public String getName() {
|
||||
public String getIdentifyingName() {
|
||||
return "Java Media Framework";
|
||||
}
|
||||
public URL getMediaURL() {
|
||||
return mediaURL;
|
||||
}
|
||||
public SmartJMFPlayer() {
|
||||
super(new GridLayout());
|
||||
}
|
||||
|
@ -79,7 +80,17 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
|||
public void destroy() throws SmartMoviePanelException {
|
||||
if (false)
|
||||
throw new SmartMoviePanelException();
|
||||
removeAllAnnotationPlayers();
|
||||
player.close();
|
||||
removeAll();
|
||||
mediaURL = null;
|
||||
isRealized = false;
|
||||
isSized = false;
|
||||
visualComponent = null;
|
||||
controlComponent = null;
|
||||
panel = null;
|
||||
vPanel = null;
|
||||
isMediaAudio = false;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
private void start() {
|
||||
|
@ -118,27 +129,27 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
|||
/*-----------------------------------------------------------------------*/
|
||||
private void showMediaComponent() {
|
||||
if (isRealized && isCached) {
|
||||
if (visualComponent == null) {
|
||||
if (panel == null) {
|
||||
setLayout(new GridLayout(1,1));
|
||||
vPanel = new JPanel();
|
||||
vPanel.setLayout( new BorderLayout() );
|
||||
if ((visualComponent = player.getVisualComponent())!= null)
|
||||
vPanel.add("Center", visualComponent);
|
||||
else
|
||||
isMediaAudio = true;
|
||||
if ((controlComponent = player.getControlPanelComponent()) != null) {
|
||||
if (visualComponent == null) //no video
|
||||
vPanel.setPreferredSize(new Dimension(400,25));
|
||||
vPanel.add("South", controlComponent);
|
||||
if (visualComponent == null) {
|
||||
if (panel == null) {
|
||||
setLayout(new GridLayout(1,1));
|
||||
vPanel = new JPanel();
|
||||
vPanel.setLayout( new BorderLayout() );
|
||||
if ((visualComponent = player.getVisualComponent())!= null)
|
||||
vPanel.add("Center", visualComponent);
|
||||
else
|
||||
isMediaAudio = true;
|
||||
if ((controlComponent = player.getControlPanelComponent()) != null) {
|
||||
if (visualComponent == null) //no video
|
||||
vPanel.setPreferredSize(new Dimension(400,25));
|
||||
vPanel.add("South", controlComponent);
|
||||
}
|
||||
}
|
||||
add(vPanel);
|
||||
parent.invalidate();
|
||||
parent.validate();
|
||||
parent.repaint();
|
||||
isSized = true;
|
||||
}
|
||||
add(vPanel);
|
||||
parent.invalidate();
|
||||
parent.validate();
|
||||
parent.repaint();
|
||||
isSized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
public synchronized void controllerUpdate(ControllerEvent event) {
|
||||
|
@ -147,23 +158,14 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
|||
if (event instanceof RealizeCompleteEvent) {
|
||||
System.out.println("received RealizeCompleteEvent event");
|
||||
isRealized = true;
|
||||
if (mediaURL.getProtocol() == "file") { //if http then wait until entire media is cached
|
||||
if (mediaURL.getProtocol().equals("file")) { //if http then wait until entire media is cached
|
||||
isCached = true;
|
||||
showMediaComponent();
|
||||
} else if (isCached) //must be http
|
||||
showMediaComponent();
|
||||
} else if (event instanceof StartEvent) {
|
||||
StartEvent se = (StartEvent)event;
|
||||
Time t = se.getMediaTime();
|
||||
long longt = t.getNanoseconds();
|
||||
Float from = new Float(longt);
|
||||
float f = (from.floatValue() / 1000000000);
|
||||
from = new Float(f);
|
||||
t = player.getStopTime();
|
||||
longt = t.getNanoseconds();
|
||||
to = new Float(longt);
|
||||
f = (to.floatValue() / 1000000000);
|
||||
to = new Float(f);
|
||||
launchAnnotationTimer(); //FIXME should have upper limit (stop time)
|
||||
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
|
@ -179,7 +181,7 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
|||
}}, 0, 15);
|
||||
} else if (event instanceof StopEvent) {
|
||||
pauseTime = player.getMediaTime();
|
||||
|
||||
cancelAnnotationTimer();
|
||||
|
||||
/*messy problems require messy solutions:
|
||||
if the slider is present, dragging it while playing creates
|
||||
|
|
|
@ -20,10 +20,258 @@ package org.thdl.media;
|
|||
|
||||
import java.awt.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import javax.swing.event.EventListenerList;
|
||||
|
||||
import org.thdl.savant.AnnotationPlayer; //should move AP to org.thdl.annotation
|
||||
|
||||
|
||||
public abstract class SmartMoviePanel extends Panel
|
||||
{
|
||||
public abstract String getName();
|
||||
//fields
|
||||
private EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
private Vector orderStartID = null, orderEndID = null;
|
||||
private Stack pileStart = null, pileEnd = null;
|
||||
private Hashtable hashStart = null, hashEnd = null;
|
||||
|
||||
private Timer annTimer = null;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
public void addAnnotationPlayer(AnnotationPlayer ap)
|
||||
{
|
||||
listenerList.add(AnnotationPlayer.class, ap);
|
||||
}
|
||||
public void removeAnnotationPlayer(AnnotationPlayer ap)
|
||||
{
|
||||
listenerList.remove(AnnotationPlayer.class, ap);
|
||||
}
|
||||
public void removeAllAnnotationPlayers() {
|
||||
listenerList = new EventListenerList();
|
||||
}
|
||||
private void fireStartAnnotation(String id)
|
||||
{
|
||||
//see javadocs on EventListenerList for how following array is structured
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
|
||||
for (int i = listeners.length-2; i>=0; i-=2)
|
||||
{
|
||||
if (listeners[i]==AnnotationPlayer.class)
|
||||
((AnnotationPlayer)listeners[i+1]).startAnnotation(id);
|
||||
}
|
||||
}
|
||||
private void fireStopAnnotation(String id)
|
||||
{
|
||||
//see javadocs on EventListenerList for how following array is structured
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
|
||||
for (int i = listeners.length-2; i>=0; i-=2)
|
||||
{
|
||||
if (listeners[i]==AnnotationPlayer.class)
|
||||
((AnnotationPlayer)listeners[i+1]).stopAnnotation(id);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
public void initForSavant(String starts, String ends, String ids) {
|
||||
String TAB_STARTS = starts;
|
||||
String TAB_ENDS = ends;
|
||||
String TAB_IDS = ids;
|
||||
|
||||
hashStart = new Hashtable();
|
||||
hashEnd = new Hashtable();
|
||||
pileStart = new Stack();
|
||||
pileEnd = new Stack();
|
||||
|
||||
StringTokenizer stIDS = new StringTokenizer(TAB_IDS, ",");
|
||||
StringTokenizer stSTARTS = new StringTokenizer(TAB_STARTS, ",");
|
||||
StringTokenizer stENDS = new StringTokenizer(TAB_ENDS, ",");
|
||||
while ((stIDS.hasMoreTokens()) && (stSTARTS.hasMoreTokens()) && (stENDS.hasMoreTokens())) {
|
||||
String sID = stIDS.nextToken();
|
||||
String sStart = stSTARTS.nextToken();
|
||||
String sEnd = stENDS.nextToken();
|
||||
try {
|
||||
Integer start = new Integer(sStart);
|
||||
hashStart.put(sID, start);
|
||||
} catch (NumberFormatException err) {
|
||||
hashStart.put(sID, new Integer(0));
|
||||
}
|
||||
try {
|
||||
Integer end = new Integer(sEnd);
|
||||
hashEnd.put(sID, end);
|
||||
} catch (NumberFormatException err) {
|
||||
hashEnd.put(sID, new Integer(0));
|
||||
}
|
||||
}
|
||||
|
||||
Vector saveOrder = new Vector();
|
||||
for (Enumeration e = hashStart.keys() ; e.hasMoreElements() ;) {
|
||||
Object o = e.nextElement();
|
||||
saveOrder.addElement(o);
|
||||
}
|
||||
orderStartID = new Vector();
|
||||
while (saveOrder.size() > 0) {
|
||||
int num = getMinusStart(saveOrder);
|
||||
orderStartID.addElement(saveOrder.elementAt(num));
|
||||
saveOrder.removeElementAt(num);
|
||||
}
|
||||
saveOrder = new Vector();
|
||||
for (Enumeration e = hashEnd.keys() ; e.hasMoreElements() ;) {
|
||||
Object o = e.nextElement();
|
||||
saveOrder.addElement(o);
|
||||
}
|
||||
orderEndID = new Vector();
|
||||
while (saveOrder.size() > 0) {
|
||||
int num = getMinusEnd(saveOrder);
|
||||
orderEndID.addElement(saveOrder.elementAt(num));
|
||||
saveOrder.removeElementAt(num);
|
||||
}
|
||||
}
|
||||
private int getMinusStart(Vector v) {
|
||||
int index = 0;
|
||||
String first = (String)v.elementAt(index);
|
||||
Integer minus = (Integer)hashStart.get(first);
|
||||
for (int i=0;i<v.size();i++) {
|
||||
String s = (String)v.elementAt(i);
|
||||
Integer f = (Integer)hashStart.get(s);
|
||||
if (minus.intValue() > f.intValue()) {
|
||||
minus = f;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
private int getMinusEnd(Vector v) {
|
||||
int index = 0;
|
||||
String first = (String)v.elementAt(index);
|
||||
Integer minus = (Integer)hashEnd.get(first);
|
||||
for (int i=0;i<v.size();i++) {
|
||||
String s = (String)v.elementAt(i);
|
||||
Integer f = (Integer)hashEnd.get(s);
|
||||
if (minus.intValue() > f.intValue()) {
|
||||
minus = f;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
public boolean cmd_isID(String theID) {
|
||||
System.out.println(hashStart.containsKey(theID));
|
||||
return hashStart.containsKey(theID);
|
||||
}
|
||||
public void cmd_playFrom(String fromID) {
|
||||
Integer from = (Integer)hashStart.get(fromID);
|
||||
try {
|
||||
cmd_playSegment(from, null);
|
||||
} catch (SmartMoviePanelException smpe) {
|
||||
smpe.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void cmd_playS(String fromID) {
|
||||
Integer from = (Integer)hashStart.get(fromID);
|
||||
Integer to = (Integer)hashEnd.get(fromID);
|
||||
try {
|
||||
cmd_playSegment(from, to);
|
||||
} catch (SmartMoviePanelException smpe) {
|
||||
smpe.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void launchAnnotationTimer() { //FIXME: should have upper limit - stop time else end time
|
||||
if (listenerList.getListenerCount() == 0) //no annotation listeners
|
||||
return;
|
||||
|
||||
int i = getCurrentTime();
|
||||
Integer from = new Integer(i);
|
||||
remplisPileStart(from, new Integer(getEndTime()));
|
||||
if (annTimer != null) {
|
||||
annTimer.cancel();
|
||||
annTimer = null;
|
||||
}
|
||||
annTimer = new java.util.Timer(true);
|
||||
annTimer.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
cmd_nextEvent();
|
||||
}}, 0, 15);
|
||||
}
|
||||
public void cancelAnnotationTimer() {
|
||||
if (listenerList.getListenerCount() == 0) //no annotation listeners
|
||||
return;
|
||||
|
||||
if (annTimer != null) {
|
||||
annTimer.cancel();
|
||||
annTimer = null;
|
||||
}
|
||||
}
|
||||
private void cmd_nextEvent() {
|
||||
Integer when = new Integer(getCurrentTime());
|
||||
if (!pileStart.empty()) {
|
||||
String id = (String)pileStart.peek();
|
||||
Integer f = (Integer)hashStart.get(id);
|
||||
if (when.intValue() >= f.intValue()) {
|
||||
id = (String)pileStart.pop();
|
||||
fireStartAnnotation(id);
|
||||
}
|
||||
}
|
||||
if (!pileEnd.empty()) {
|
||||
String id = (String)pileEnd.peek();
|
||||
Integer f = (Integer)hashEnd.get(id);
|
||||
if (when.intValue() >= f.intValue()) {
|
||||
id = (String)pileEnd.pop();
|
||||
fireStopAnnotation(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void vide_Pile() {
|
||||
while (!pileEnd.empty()) { //vider la pile des items qui ne sont pas
|
||||
String id = (String)pileEnd.pop(); //encore fini
|
||||
if (pileStart.search(id) == -1) {
|
||||
fireStopAnnotation(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* empties the pile, and then reconstructs it to consist of all ids
|
||||
whose start time or end time is included between start and end. */
|
||||
|
||||
private void remplisPileStart(Integer start, Integer end) {
|
||||
vide_Pile();
|
||||
pileStart.removeAllElements();
|
||||
pileEnd.removeAllElements();
|
||||
for (int i=orderEndID.size()-1; i!=-1; i--) {
|
||||
String id = (String)orderEndID.elementAt(i);
|
||||
Integer f = (Integer)hashEnd.get(id);
|
||||
if ((f.intValue() > start.intValue()) && (f.intValue() <= end.intValue())) {
|
||||
pileEnd.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
/* note: we are also interested in ids that begin before start,
|
||||
provided they overlap with the interval start-end. */
|
||||
|
||||
for (int i=orderStartID.size()-1; i!=-1; i--) {
|
||||
String id = (String)orderStartID.elementAt(i);
|
||||
Integer f = (Integer)hashStart.get(id);
|
||||
Integer f2 = (Integer)hashEnd.get(id);
|
||||
if ( (f.intValue() >= start.intValue() && f.intValue() < end.intValue()) ||
|
||||
(f.intValue() < start.intValue() && f2.intValue() > start.intValue())) {
|
||||
pileStart.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
//constructor
|
||||
public SmartMoviePanel(GridLayout layout)
|
||||
{
|
||||
super(layout);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
//abstract methods
|
||||
|
||||
|
||||
public abstract String getIdentifyingName();
|
||||
public abstract URL getMediaURL();
|
||||
public abstract void setParentContainer(Container c);
|
||||
|
||||
//helper methods - initialize
|
||||
|
@ -44,9 +292,4 @@ public abstract class SmartMoviePanel extends Panel
|
|||
|
||||
//helper methods - cleanup
|
||||
public abstract void destroy() throws SmartMoviePanelException;
|
||||
//constructor
|
||||
public SmartMoviePanel(GridLayout layout)
|
||||
{
|
||||
super(layout);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,35 +19,63 @@ Contributor(s): ______________________________________.
|
|||
package org.thdl.media;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.thdl.util.*;
|
||||
|
||||
import org.thdl.util.ThdlDebug;
|
||||
|
||||
public class SmartPlayerFactory {
|
||||
public static List moviePlayers;
|
||||
|
||||
/** You cannot instantiate this class. */
|
||||
private SmartPlayerFactory() { }
|
||||
|
||||
static final String[] possiblePlayers
|
||||
= {"org.thdl.media.SmartJMFPlayer", "org.thdl.media.SmartQT4JPlayer"};
|
||||
public static List getAllAvailableSmartPlayers() {
|
||||
String os;
|
||||
try {
|
||||
os = System.getProperty("os.name").toLowerCase();
|
||||
} catch (SecurityException e) {
|
||||
os = "unknown";
|
||||
}
|
||||
|
||||
static SmartMoviePanel[] getAllAvailableSmartPlayers() {
|
||||
List moviePlayers = new ArrayList();
|
||||
String defaultPlayer;
|
||||
if (os.indexOf("mac") != -1) //macs default to org.thdl.media.SmartQT4JPlayer
|
||||
defaultPlayer = ThdlOptions.getStringOption("thdl.media.player", "org.thdl.media.SmartQT4JPlayer");
|
||||
else if (os.indexOf("windows") != -1) //windows defaults to SmartJMFPlayer
|
||||
defaultPlayer = ThdlOptions.getStringOption("thdl.media.player", "org.thdl.media.SmartJMFPlayer");
|
||||
else //put linux etc. here
|
||||
defaultPlayer = ThdlOptions.getStringOption("thdl.media.player", "org.thdl.media.SmartJMFPlayer");
|
||||
|
||||
String[] possiblePlayers;
|
||||
if (defaultPlayer.equals("org.thdl.media.SmartJMFPlayer"))
|
||||
possiblePlayers = new String[] {"org.thdl.media.SmartJMFPlayer", "org.thdl.media.SmartQT4JPlayer"};
|
||||
else
|
||||
possiblePlayers = new String[] {"org.thdl.media.SmartQT4JPlayer", "org.thdl.media.SmartJMFPlayer"};
|
||||
|
||||
moviePlayers = new ArrayList();
|
||||
for (int i=0; i<possiblePlayers.length; i++) {
|
||||
try {
|
||||
Class mediaClass = Class.forName(possiblePlayers[i]);
|
||||
|
||||
//FIXME: playerClasses.add(mediaClass);
|
||||
|
||||
SmartMoviePanel smp = (SmartMoviePanel)mediaClass.newInstance();
|
||||
moviePlayers.add(smp);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
cnfe.printStackTrace();
|
||||
System.out.println("No big deal: class " + possiblePlayers[i] + " not found.");
|
||||
} catch (LinkageError lie) {
|
||||
System.out.println("No big deal: class " + possiblePlayers[i] + " not found.");
|
||||
} catch (InstantiationException ie) {
|
||||
ie.printStackTrace();
|
||||
ThdlDebug.noteIffyCode();
|
||||
} catch (SecurityException se) {
|
||||
se.printStackTrace();
|
||||
} catch (IllegalAccessException iae) {
|
||||
iae.printStackTrace();
|
||||
ThdlDebug.noteIffyCode();
|
||||
}
|
||||
}
|
||||
return (SmartMoviePanel[])moviePlayers.toArray();
|
||||
return moviePlayers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,16 +47,21 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
|
||||
private MovieController controller;
|
||||
|
||||
private TimeBaseRateCallBack theMoviesRateCallback;
|
||||
private TimeBaseExtremesCallBack theMoviesExtremeCallback;
|
||||
private TimeBaseTimeJumpCallBack theMoviesTimeJumpCallback;
|
||||
private RateCallBack rateCallBack = null;
|
||||
private TimeJumpCallBack jumpCallBack = null;
|
||||
|
||||
private TimeBaseTimeCallBack theMoviesTimeCallback;
|
||||
private TimeBaseTimeCallBackStopper theStopper;
|
||||
|
||||
private URL mediaUrl = null;
|
||||
|
||||
//accessors
|
||||
public String getName() {
|
||||
public String getIdentifyingName() {
|
||||
return "Quicktime for Java";
|
||||
}
|
||||
public URL getMediaURL() {
|
||||
return mediaUrl;
|
||||
}
|
||||
public void setParentContainer(Container c) {
|
||||
}
|
||||
public void setPlayer(QTPlayer player)
|
||||
|
@ -81,6 +86,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
m = m.fromDataRef( movieDataRef, StdQTConstants.newMovieActive );
|
||||
setMovie(m);
|
||||
getMovie().setTimeScale(1000);
|
||||
mediaUrl = movieURL;
|
||||
}
|
||||
catch(QTException qte)
|
||||
{
|
||||
|
@ -183,40 +189,43 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
this.add( getCanvas() );
|
||||
TimeBase theMoviesTimeBase = getMovie().getTimeBase();
|
||||
|
||||
// this callback is triggered when the rate of the movie changes
|
||||
theMoviesRateCallback = new TimeBaseRateCallBack(theMoviesTimeBase, 1.0F, StdQTConstants.triggerRateChange);
|
||||
// theMoviesRateCallback.callMeWhen();
|
||||
|
||||
// this callback is triggered when the movie ends
|
||||
theMoviesExtremeCallback = new TimeBaseExtremesCallBack(theMoviesTimeBase, StdQTConstants.triggerAtStop);
|
||||
// theMoviesExtremeCallback.callMeWhen();
|
||||
|
||||
// this callback is triggered when the movie starts
|
||||
theMoviesExtremeCallback = new TimeBaseExtremesCallBack(theMoviesTimeBase, StdQTConstants.triggerAtStart);
|
||||
// theMoviesExtremeCallback.callMeWhen();
|
||||
|
||||
// this callback is triggered when there is a jump in the timebase
|
||||
theMoviesTimeJumpCallback = new TimeBaseTimeJumpCallBack(theMoviesTimeBase);
|
||||
// theMoviesTimeJumpCallback.callMeWhen();
|
||||
|
||||
// this schedules the time callback once every 2 seconds
|
||||
// this callback is triggered at a specific time interval
|
||||
theMoviesTimeCallback = new TimeBaseTimeCallBack(theMoviesTimeBase, 1, 2, StdQTConstants.triggerTimeEither);
|
||||
// theMoviesTimeCallback.callMeWhen();
|
||||
|
||||
//Using the Timer class you can get rescheduled properly and get callbacks at the set intervals. It uses the same callback
|
||||
//mechanism of internally of the TimeCallback.
|
||||
//Its recomended to use this Timer class to do callbacks , which would take care of the time base time changes and
|
||||
//recscheduling of the tickle method .
|
||||
Timer timer = new Timer(1, 2, new Tickler(), getMovie() ); //FIXME: is this used?
|
||||
// timer.setActive(true);
|
||||
// this callback is triggered when the rate of the movie changes (0 is stopped, >0 is playing)
|
||||
rateCallBack = new RateCallBack(theMoviesTimeBase, 0, StdQTConstants.triggerRateChange) {
|
||||
public void execute() {
|
||||
System.out.println("Rate changed to: " + String.valueOf(rateWhenCalled));
|
||||
if (rateWhenCalled > 0)
|
||||
launchAnnotationTimer();
|
||||
else
|
||||
cancelAnnotationTimer();
|
||||
schedule(this);
|
||||
}
|
||||
};
|
||||
schedule(rateCallBack);
|
||||
|
||||
// this callback is triggered when there is a jump in the timebase, ie when the slider control is adjusted
|
||||
jumpCallBack = new TimeJumpCallBack(theMoviesTimeBase) {
|
||||
public void execute() {
|
||||
System.out.println("Time Jump. New rate: " + String.valueOf(rateWhenCalled));
|
||||
if (rateWhenCalled > 0)
|
||||
launchAnnotationTimer();
|
||||
schedule(this);
|
||||
}
|
||||
};
|
||||
schedule(jumpCallBack);
|
||||
}
|
||||
catch(QTException qte)
|
||||
{
|
||||
qte.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void schedule(QTCallBack callBack) {
|
||||
try {
|
||||
callBack.callMeWhen();
|
||||
} catch (StdQTException stdqte) {
|
||||
stdqte.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//contract methods - control media
|
||||
public void cmd_playOn() throws SmartMoviePanelException
|
||||
|
@ -234,6 +243,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
{
|
||||
try
|
||||
{
|
||||
getPlayer().setRate(0);
|
||||
getPlayer().setTime( startTime.intValue() );
|
||||
|
||||
int value;
|
||||
|
@ -248,13 +258,16 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
|
||||
cmd_playOn();
|
||||
|
||||
/*
|
||||
System.out.println("Set start time to " +startTime.intValue() );
|
||||
System.out.println("Set stop time " +stopTime.intValue() );
|
||||
if (stopTime != null)
|
||||
System.out.println("Set stop time " +stopTime.intValue() );
|
||||
System.out.println("Current time " +getPlayer().getTime() );
|
||||
System.out.println("Time Stopper's stop trigger " +theStopper.getCallTime() );
|
||||
if (stopTime != null)
|
||||
System.out.println("Time Stopper's stop trigger " +theStopper.getCallTime() );
|
||||
System.out.println("Player Scale: " +getPlayer().getScale() );
|
||||
System.out.println("Movie Scale: " +getMovie().getTimeScale() );
|
||||
|
||||
*/
|
||||
}
|
||||
catch (SmartMoviePanelException smpe) {}
|
||||
catch (StdQTException sqte) {}
|
||||
|
@ -273,12 +286,17 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
}
|
||||
|
||||
//contract methods - media status
|
||||
public boolean isInitialized()
|
||||
{
|
||||
return true;
|
||||
public boolean isInitialized() {
|
||||
return true; //FIXME what should this do?
|
||||
}
|
||||
public boolean isPlaying() {
|
||||
return false; //FIXME
|
||||
try {
|
||||
if (getMovie().getRate() > 0)
|
||||
return true;
|
||||
} catch (StdQTException stdqte) {
|
||||
stdqte.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public int getCurrentTime()
|
||||
{
|
||||
|
@ -286,7 +304,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
return getMovie().getTime();
|
||||
} catch (StdQTException stqte) {
|
||||
stqte.printStackTrace();
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public int getEndTime()
|
||||
|
@ -295,70 +313,22 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
return getMovie().getDuration();
|
||||
} catch (StdQTException stqte) {
|
||||
stqte.printStackTrace();
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//helper methods - QT4J
|
||||
|
||||
/*
|
||||
public void startupQTSession()
|
||||
{
|
||||
//Initialize a QT session and add a test image
|
||||
|
||||
//These three try/catch blocks come from PlayMovie.java copyright
|
||||
// Apple Co. I'm using it to test that QT and QT4Java exist
|
||||
try
|
||||
{
|
||||
if (QTSession.isInitialized() == false)
|
||||
QTSession.open();
|
||||
}
|
||||
catch (NoClassDefFoundError er)
|
||||
{
|
||||
add (new Label ("Can't Find QTJava classes"), "North");
|
||||
add (new Label ("Check install and try again"), "South");
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
// this is thrown by MRJ trying to find QTSession class
|
||||
add (new Label ("Can't Find QTJava classes"), "North");
|
||||
add (new Label ("Check install and try again"), "South");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// do a dynamic test for QTException
|
||||
//so the QTException class is not loaded unless
|
||||
// an unknown exception is thrown by the runtime
|
||||
if (e instanceof ClassNotFoundException || e instanceof java.io.FileNotFoundException)
|
||||
{
|
||||
add (new Label ("Can't Find QTJava classes"), "North");
|
||||
add (new Label ("Check install and try again"), "South");
|
||||
}
|
||||
else if (e instanceof QTException)
|
||||
{
|
||||
add (new Label ("Problem with QuickTime install"), "North");
|
||||
if (((QTException)e).errorCode() == -2093)
|
||||
add (new Label ("QuickTime must be installed"), "South");
|
||||
else
|
||||
add (new Label (e.getMessage()), "South");
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
setCanvas( new QTCanvas(QTCanvas.kInitialSize, 0.5F, 0.5F) );
|
||||
this.add( getCanvas() );
|
||||
getCanvas().setClient(ImageDrawer.getQTLogo(), true);
|
||||
}
|
||||
catch(QTException qte)
|
||||
{
|
||||
qte.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
if (rateCallBack != null)
|
||||
rateCallBack.cancelAndCleanup();
|
||||
if (jumpCallBack != null)
|
||||
jumpCallBack.cancelAndCleanup();
|
||||
removeAllAnnotationPlayers();
|
||||
QTSession.close();
|
||||
removeAll();
|
||||
mediaUrl = null;
|
||||
System.out.println("Clean up performed.");
|
||||
}
|
||||
|
||||
|
@ -366,7 +336,6 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
public SmartQT4JPlayer(Container cont, URL mediaURL)
|
||||
{
|
||||
super( new GridLayout() );
|
||||
// startupQTSession();
|
||||
try {
|
||||
loadMovie(mediaURL);
|
||||
} catch (SmartMoviePanelException smpe) {
|
||||
|
@ -376,101 +345,10 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
public SmartQT4JPlayer()
|
||||
{
|
||||
super( new GridLayout() );
|
||||
// startupQTSession();
|
||||
}
|
||||
|
||||
// inner classes
|
||||
/**
|
||||
* This class extends the RateCallBack class and provides an execute routine
|
||||
* that is invoked by the callback when the rate of the movie changes
|
||||
*
|
||||
*@author travis
|
||||
*@created September 3, 2002
|
||||
*/
|
||||
|
||||
public class TimeBaseRateCallBack extends RateCallBack
|
||||
{
|
||||
public TimeBaseRateCallBack(TimeBase tb, float rate, int flag) throws QTException
|
||||
{
|
||||
super(tb, rate, flag);
|
||||
}
|
||||
|
||||
public void execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("--- RateCallBack@ratechange---");
|
||||
|
||||
cancel();
|
||||
//reschedule
|
||||
callMeWhen();
|
||||
|
||||
} catch (StdQTException e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements a method that is called when the movie stops
|
||||
*
|
||||
*@author travis
|
||||
*@created September 3, 2002
|
||||
*/
|
||||
|
||||
class TimeBaseExtremesCallBack extends quicktime.std.clocks.ExtremesCallBack
|
||||
{
|
||||
|
||||
public TimeBaseExtremesCallBack(TimeBase tb, int flag) throws QTException
|
||||
{
|
||||
super(tb, flag);
|
||||
}
|
||||
|
||||
public void execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("--- ExtremesCallBack@stop---");
|
||||
|
||||
//cancel
|
||||
cancel();
|
||||
//reschedule
|
||||
callMeWhen();
|
||||
}
|
||||
catch (StdQTException e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends the TimeJumpCallBack class to provide a method that is
|
||||
* called when the timebase of the movie changes (IE, if the user clicks in
|
||||
* the movie controller)
|
||||
*
|
||||
*@author travis
|
||||
*@created September 3, 2002
|
||||
*/
|
||||
|
||||
class TimeBaseTimeJumpCallBack extends quicktime.std.clocks.TimeJumpCallBack
|
||||
{
|
||||
public TimeBaseTimeJumpCallBack(TimeBase tb) throws QTException
|
||||
{
|
||||
super(tb);
|
||||
}
|
||||
|
||||
public void execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("--- TimeJumpCallBack---");
|
||||
|
||||
cancel();
|
||||
//reschedule
|
||||
callMeWhen();
|
||||
}
|
||||
catch (StdQTException e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
class TimeBaseTimeCallBack extends quicktime.std.clocks.TimeCallBack
|
||||
{
|
||||
|
@ -490,7 +368,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
{
|
||||
try
|
||||
{
|
||||
System.out.println("--- TimeCallBack@triggerTimeEither--- called at:" + timeWhenCalledMsecs + "msecs");
|
||||
// System.out.println("--- TimeCallBack@triggerTimeEither--- called at:" + timeWhenCalledMsecs + "msecs");
|
||||
|
||||
cancel();
|
||||
//reschedule
|
||||
|
@ -512,19 +390,22 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
{
|
||||
public void execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
/*
|
||||
System.out.println("---TimeCallBackStopper--- called at:" + timeWhenCalledMsecs + "msecs");
|
||||
System.out.println("---TimeCallBackStopper--- callTime is: " + getCallTime() + " msecs");
|
||||
*/
|
||||
cmd_stop();
|
||||
|
||||
/*
|
||||
System.out.println("---TimeCallBackStopper--- Player time is: " + getPlayer().getTime() + " msecs");
|
||||
System.out.println("---TimeCallBackStopper--- Movie time is: " + getMovie().getTime() + " msecs");
|
||||
*/
|
||||
|
||||
cancelAndCleanup();
|
||||
//reschedule
|
||||
//callMeWhen();
|
||||
}
|
||||
catch (StdQTException e) {}
|
||||
catch (SmartMoviePanelException smpe) {}
|
||||
}
|
||||
public TimeBaseTimeCallBackStopper(TimeBase tb, int scale, int value, int flags) throws QTException
|
||||
|
@ -533,18 +414,4 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public class Tickler implements Ticklish
|
||||
{
|
||||
public void timeChanged(int newTime) throws QTException
|
||||
{
|
||||
System.out.println("* * * * Timer Class * * * timeChanged at:" + newTime);
|
||||
}
|
||||
|
||||
public boolean tickle(float er, int time) throws QTException
|
||||
{
|
||||
System.out.println("* * * * Timer Class * * * tickle at:" + time);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue