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
|
public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListener
|
||||||
{
|
{
|
||||||
private EventListenerList listenerList = new EventListenerList();
|
|
||||||
|
|
||||||
public URL mediaURL;
|
public URL mediaURL;
|
||||||
|
|
||||||
private Player player = null;
|
private Player player = null;
|
||||||
|
@ -54,9 +52,12 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
||||||
|
|
||||||
private Float to = null;
|
private Float to = null;
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
public String getName() {
|
public String getIdentifyingName() {
|
||||||
return "Java Media Framework";
|
return "Java Media Framework";
|
||||||
}
|
}
|
||||||
|
public URL getMediaURL() {
|
||||||
|
return mediaURL;
|
||||||
|
}
|
||||||
public SmartJMFPlayer() {
|
public SmartJMFPlayer() {
|
||||||
super(new GridLayout());
|
super(new GridLayout());
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,17 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
||||||
public void destroy() throws SmartMoviePanelException {
|
public void destroy() throws SmartMoviePanelException {
|
||||||
if (false)
|
if (false)
|
||||||
throw new SmartMoviePanelException();
|
throw new SmartMoviePanelException();
|
||||||
|
removeAllAnnotationPlayers();
|
||||||
player.close();
|
player.close();
|
||||||
|
removeAll();
|
||||||
|
mediaURL = null;
|
||||||
|
isRealized = false;
|
||||||
|
isSized = false;
|
||||||
|
visualComponent = null;
|
||||||
|
controlComponent = null;
|
||||||
|
panel = null;
|
||||||
|
vPanel = null;
|
||||||
|
isMediaAudio = false;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
private void start() {
|
private void start() {
|
||||||
|
@ -147,23 +158,14 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
||||||
if (event instanceof RealizeCompleteEvent) {
|
if (event instanceof RealizeCompleteEvent) {
|
||||||
System.out.println("received RealizeCompleteEvent event");
|
System.out.println("received RealizeCompleteEvent event");
|
||||||
isRealized = true;
|
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;
|
isCached = true;
|
||||||
showMediaComponent();
|
showMediaComponent();
|
||||||
} else if (isCached) //must be http
|
} else if (isCached) //must be http
|
||||||
showMediaComponent();
|
showMediaComponent();
|
||||||
} else if (event instanceof StartEvent) {
|
} else if (event instanceof StartEvent) {
|
||||||
StartEvent se = (StartEvent)event;
|
launchAnnotationTimer(); //FIXME should have upper limit (stop time)
|
||||||
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);
|
|
||||||
if (timer != null)
|
if (timer != null)
|
||||||
{
|
{
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
|
@ -179,7 +181,7 @@ public class SmartJMFPlayer extends SmartMoviePanel implements ControllerListene
|
||||||
}}, 0, 15);
|
}}, 0, 15);
|
||||||
} else if (event instanceof StopEvent) {
|
} else if (event instanceof StopEvent) {
|
||||||
pauseTime = player.getMediaTime();
|
pauseTime = player.getMediaTime();
|
||||||
|
cancelAnnotationTimer();
|
||||||
|
|
||||||
/*messy problems require messy solutions:
|
/*messy problems require messy solutions:
|
||||||
if the slider is present, dragging it while playing creates
|
if the slider is present, dragging it while playing creates
|
||||||
|
|
|
@ -20,10 +20,258 @@ package org.thdl.media;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.net.*;
|
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 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);
|
public abstract void setParentContainer(Container c);
|
||||||
|
|
||||||
//helper methods - initialize
|
//helper methods - initialize
|
||||||
|
@ -44,9 +292,4 @@ public abstract class SmartMoviePanel extends Panel
|
||||||
|
|
||||||
//helper methods - cleanup
|
//helper methods - cleanup
|
||||||
public abstract void destroy() throws SmartMoviePanelException;
|
public abstract void destroy() throws SmartMoviePanelException;
|
||||||
//constructor
|
|
||||||
public SmartMoviePanel(GridLayout layout)
|
|
||||||
{
|
|
||||||
super(layout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,35 +19,63 @@ Contributor(s): ______________________________________.
|
||||||
package org.thdl.media;
|
package org.thdl.media;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.thdl.util.*;
|
||||||
|
|
||||||
import org.thdl.util.ThdlDebug;
|
import org.thdl.util.ThdlDebug;
|
||||||
|
|
||||||
public class SmartPlayerFactory {
|
public class SmartPlayerFactory {
|
||||||
|
public static List moviePlayers;
|
||||||
|
|
||||||
/** You cannot instantiate this class. */
|
/** You cannot instantiate this class. */
|
||||||
private SmartPlayerFactory() { }
|
private SmartPlayerFactory() { }
|
||||||
|
|
||||||
static final String[] possiblePlayers
|
public static List getAllAvailableSmartPlayers() {
|
||||||
= {"org.thdl.media.SmartJMFPlayer", "org.thdl.media.SmartQT4JPlayer"};
|
String os;
|
||||||
|
try {
|
||||||
|
os = System.getProperty("os.name").toLowerCase();
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
os = "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
static SmartMoviePanel[] getAllAvailableSmartPlayers() {
|
String defaultPlayer;
|
||||||
List moviePlayers = new ArrayList();
|
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++) {
|
for (int i=0; i<possiblePlayers.length; i++) {
|
||||||
try {
|
try {
|
||||||
Class mediaClass = Class.forName(possiblePlayers[i]);
|
Class mediaClass = Class.forName(possiblePlayers[i]);
|
||||||
|
|
||||||
//FIXME: playerClasses.add(mediaClass);
|
//FIXME: playerClasses.add(mediaClass);
|
||||||
|
|
||||||
SmartMoviePanel smp = (SmartMoviePanel)mediaClass.newInstance();
|
SmartMoviePanel smp = (SmartMoviePanel)mediaClass.newInstance();
|
||||||
moviePlayers.add(smp);
|
moviePlayers.add(smp);
|
||||||
} catch (ClassNotFoundException cnfe) {
|
} 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) {
|
} catch (InstantiationException ie) {
|
||||||
ie.printStackTrace();
|
ie.printStackTrace();
|
||||||
ThdlDebug.noteIffyCode();
|
} catch (SecurityException se) {
|
||||||
|
se.printStackTrace();
|
||||||
} catch (IllegalAccessException iae) {
|
} catch (IllegalAccessException iae) {
|
||||||
iae.printStackTrace();
|
iae.printStackTrace();
|
||||||
ThdlDebug.noteIffyCode();
|
ThdlDebug.noteIffyCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (SmartMoviePanel[])moviePlayers.toArray();
|
return moviePlayers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,16 +47,21 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
|
|
||||||
private MovieController controller;
|
private MovieController controller;
|
||||||
|
|
||||||
private TimeBaseRateCallBack theMoviesRateCallback;
|
private RateCallBack rateCallBack = null;
|
||||||
private TimeBaseExtremesCallBack theMoviesExtremeCallback;
|
private TimeJumpCallBack jumpCallBack = null;
|
||||||
private TimeBaseTimeJumpCallBack theMoviesTimeJumpCallback;
|
|
||||||
private TimeBaseTimeCallBack theMoviesTimeCallback;
|
private TimeBaseTimeCallBack theMoviesTimeCallback;
|
||||||
private TimeBaseTimeCallBackStopper theStopper;
|
private TimeBaseTimeCallBackStopper theStopper;
|
||||||
|
|
||||||
|
private URL mediaUrl = null;
|
||||||
|
|
||||||
//accessors
|
//accessors
|
||||||
public String getName() {
|
public String getIdentifyingName() {
|
||||||
return "Quicktime for Java";
|
return "Quicktime for Java";
|
||||||
}
|
}
|
||||||
|
public URL getMediaURL() {
|
||||||
|
return mediaUrl;
|
||||||
|
}
|
||||||
public void setParentContainer(Container c) {
|
public void setParentContainer(Container c) {
|
||||||
}
|
}
|
||||||
public void setPlayer(QTPlayer player)
|
public void setPlayer(QTPlayer player)
|
||||||
|
@ -81,6 +86,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
m = m.fromDataRef( movieDataRef, StdQTConstants.newMovieActive );
|
m = m.fromDataRef( movieDataRef, StdQTConstants.newMovieActive );
|
||||||
setMovie(m);
|
setMovie(m);
|
||||||
getMovie().setTimeScale(1000);
|
getMovie().setTimeScale(1000);
|
||||||
|
mediaUrl = movieURL;
|
||||||
}
|
}
|
||||||
catch(QTException qte)
|
catch(QTException qte)
|
||||||
{
|
{
|
||||||
|
@ -183,34 +189,29 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
this.add( getCanvas() );
|
this.add( getCanvas() );
|
||||||
TimeBase theMoviesTimeBase = getMovie().getTimeBase();
|
TimeBase theMoviesTimeBase = getMovie().getTimeBase();
|
||||||
|
|
||||||
// this callback is triggered when the rate of the movie changes
|
// this callback is triggered when the rate of the movie changes (0 is stopped, >0 is playing)
|
||||||
theMoviesRateCallback = new TimeBaseRateCallBack(theMoviesTimeBase, 1.0F, StdQTConstants.triggerRateChange);
|
rateCallBack = new RateCallBack(theMoviesTimeBase, 0, StdQTConstants.triggerRateChange) {
|
||||||
// theMoviesRateCallback.callMeWhen();
|
public void execute() {
|
||||||
|
System.out.println("Rate changed to: " + String.valueOf(rateWhenCalled));
|
||||||
// this callback is triggered when the movie ends
|
if (rateWhenCalled > 0)
|
||||||
theMoviesExtremeCallback = new TimeBaseExtremesCallBack(theMoviesTimeBase, StdQTConstants.triggerAtStop);
|
launchAnnotationTimer();
|
||||||
// theMoviesExtremeCallback.callMeWhen();
|
else
|
||||||
|
cancelAnnotationTimer();
|
||||||
// this callback is triggered when the movie starts
|
schedule(this);
|
||||||
theMoviesExtremeCallback = new TimeBaseExtremesCallBack(theMoviesTimeBase, StdQTConstants.triggerAtStart);
|
}
|
||||||
// theMoviesExtremeCallback.callMeWhen();
|
};
|
||||||
|
schedule(rateCallBack);
|
||||||
// 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 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)
|
catch(QTException qte)
|
||||||
{
|
{
|
||||||
|
@ -218,6 +219,14 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void schedule(QTCallBack callBack) {
|
||||||
|
try {
|
||||||
|
callBack.callMeWhen();
|
||||||
|
} catch (StdQTException stdqte) {
|
||||||
|
stdqte.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//contract methods - control media
|
//contract methods - control media
|
||||||
public void cmd_playOn() throws SmartMoviePanelException
|
public void cmd_playOn() throws SmartMoviePanelException
|
||||||
{
|
{
|
||||||
|
@ -234,6 +243,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
getPlayer().setRate(0);
|
||||||
getPlayer().setTime( startTime.intValue() );
|
getPlayer().setTime( startTime.intValue() );
|
||||||
|
|
||||||
int value;
|
int value;
|
||||||
|
@ -248,13 +258,16 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
|
|
||||||
cmd_playOn();
|
cmd_playOn();
|
||||||
|
|
||||||
|
/*
|
||||||
System.out.println("Set start time to " +startTime.intValue() );
|
System.out.println("Set start time to " +startTime.intValue() );
|
||||||
|
if (stopTime != null)
|
||||||
System.out.println("Set stop time " +stopTime.intValue() );
|
System.out.println("Set stop time " +stopTime.intValue() );
|
||||||
System.out.println("Current time " +getPlayer().getTime() );
|
System.out.println("Current time " +getPlayer().getTime() );
|
||||||
|
if (stopTime != null)
|
||||||
System.out.println("Time Stopper's stop trigger " +theStopper.getCallTime() );
|
System.out.println("Time Stopper's stop trigger " +theStopper.getCallTime() );
|
||||||
System.out.println("Player Scale: " +getPlayer().getScale() );
|
System.out.println("Player Scale: " +getPlayer().getScale() );
|
||||||
System.out.println("Movie Scale: " +getMovie().getTimeScale() );
|
System.out.println("Movie Scale: " +getMovie().getTimeScale() );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
catch (SmartMoviePanelException smpe) {}
|
catch (SmartMoviePanelException smpe) {}
|
||||||
catch (StdQTException sqte) {}
|
catch (StdQTException sqte) {}
|
||||||
|
@ -273,12 +286,17 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
}
|
}
|
||||||
|
|
||||||
//contract methods - media status
|
//contract methods - media status
|
||||||
public boolean isInitialized()
|
public boolean isInitialized() {
|
||||||
{
|
return true; //FIXME what should this do?
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
public boolean isPlaying() {
|
public boolean isPlaying() {
|
||||||
return false; //FIXME
|
try {
|
||||||
|
if (getMovie().getRate() > 0)
|
||||||
|
return true;
|
||||||
|
} catch (StdQTException stdqte) {
|
||||||
|
stdqte.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
public int getCurrentTime()
|
public int getCurrentTime()
|
||||||
{
|
{
|
||||||
|
@ -286,7 +304,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
return getMovie().getTime();
|
return getMovie().getTime();
|
||||||
} catch (StdQTException stqte) {
|
} catch (StdQTException stqte) {
|
||||||
stqte.printStackTrace();
|
stqte.printStackTrace();
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int getEndTime()
|
public int getEndTime()
|
||||||
|
@ -295,70 +313,22 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
return getMovie().getDuration();
|
return getMovie().getDuration();
|
||||||
} catch (StdQTException stqte) {
|
} catch (StdQTException stqte) {
|
||||||
stqte.printStackTrace();
|
stqte.printStackTrace();
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//helper methods - QT4J
|
//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()
|
public void destroy()
|
||||||
{
|
{
|
||||||
|
if (rateCallBack != null)
|
||||||
|
rateCallBack.cancelAndCleanup();
|
||||||
|
if (jumpCallBack != null)
|
||||||
|
jumpCallBack.cancelAndCleanup();
|
||||||
|
removeAllAnnotationPlayers();
|
||||||
QTSession.close();
|
QTSession.close();
|
||||||
|
removeAll();
|
||||||
|
mediaUrl = null;
|
||||||
System.out.println("Clean up performed.");
|
System.out.println("Clean up performed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +336,6 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
public SmartQT4JPlayer(Container cont, URL mediaURL)
|
public SmartQT4JPlayer(Container cont, URL mediaURL)
|
||||||
{
|
{
|
||||||
super( new GridLayout() );
|
super( new GridLayout() );
|
||||||
// startupQTSession();
|
|
||||||
try {
|
try {
|
||||||
loadMovie(mediaURL);
|
loadMovie(mediaURL);
|
||||||
} catch (SmartMoviePanelException smpe) {
|
} catch (SmartMoviePanelException smpe) {
|
||||||
|
@ -376,101 +345,10 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
public SmartQT4JPlayer()
|
public SmartQT4JPlayer()
|
||||||
{
|
{
|
||||||
super( new GridLayout() );
|
super( new GridLayout() );
|
||||||
// startupQTSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inner classes
|
// 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
|
class TimeBaseTimeCallBack extends quicktime.std.clocks.TimeCallBack
|
||||||
{
|
{
|
||||||
|
@ -490,7 +368,7 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("--- TimeCallBack@triggerTimeEither--- called at:" + timeWhenCalledMsecs + "msecs");
|
// System.out.println("--- TimeCallBack@triggerTimeEither--- called at:" + timeWhenCalledMsecs + "msecs");
|
||||||
|
|
||||||
cancel();
|
cancel();
|
||||||
//reschedule
|
//reschedule
|
||||||
|
@ -512,19 +390,22 @@ public class SmartQT4JPlayer extends SmartMoviePanel
|
||||||
{
|
{
|
||||||
public void execute()
|
public void execute()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
/*
|
||||||
System.out.println("---TimeCallBackStopper--- called at:" + timeWhenCalledMsecs + "msecs");
|
System.out.println("---TimeCallBackStopper--- called at:" + timeWhenCalledMsecs + "msecs");
|
||||||
System.out.println("---TimeCallBackStopper--- callTime is: " + getCallTime() + " msecs");
|
System.out.println("---TimeCallBackStopper--- callTime is: " + getCallTime() + " msecs");
|
||||||
|
*/
|
||||||
cmd_stop();
|
cmd_stop();
|
||||||
|
|
||||||
|
/*
|
||||||
System.out.println("---TimeCallBackStopper--- Player time is: " + getPlayer().getTime() + " msecs");
|
System.out.println("---TimeCallBackStopper--- Player time is: " + getPlayer().getTime() + " msecs");
|
||||||
System.out.println("---TimeCallBackStopper--- Movie time is: " + getMovie().getTime() + " msecs");
|
System.out.println("---TimeCallBackStopper--- Movie time is: " + getMovie().getTime() + " msecs");
|
||||||
|
*/
|
||||||
|
|
||||||
cancelAndCleanup();
|
cancelAndCleanup();
|
||||||
//reschedule
|
//reschedule
|
||||||
//callMeWhen();
|
//callMeWhen();
|
||||||
}
|
}
|
||||||
catch (StdQTException e) {}
|
|
||||||
catch (SmartMoviePanelException smpe) {}
|
catch (SmartMoviePanelException smpe) {}
|
||||||
}
|
}
|
||||||
public TimeBaseTimeCallBackStopper(TimeBase tb, int scale, int value, int flags) throws QTException
|
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