masi
Interface MASI


public interface MASI

Media Applet Synchronization Interface (MASI)


MASI can be used to synchronize several media Applets located in one document to make them cooperate and deliver the same multimedia content. An example of this would be to combine a whiteboard Applet with an audio streaming Applet to deliver some lecture over the world wide web.
The underlying concept of this Interface is the notion of a frame. All methods that address offsets use frames as their basic unit. A frame is a certain amount of time. Frames are atomic in the sense that there are no fractions of frames. Every Applet has to provide methods to convert the abstract unit frame into concrete amounts of time. The amounts of time should be chosen as small as possible to allow fine granular control of the streams.
Technically speaking an Applet must implement this Interface and use AppletContext.getApplets() to get all other Applets in the document. Then one should check every returned object whether it is instanceof masi.MASI. Sometimes however, the Enumeration returned by getApplets() returns elements containing null. Therefore it is wise, not only to check for null elemnts, but also to repeat the getApplets() call in this case. The next step is to verify the version, which can safely be obtained by reading MASIVERSION.
One problem is, that there is no proper way to find out what kind of media each Applet is delivering.
In order to solve this, Applets can get each other's instances by the AppletContext.getApplet(String name) method.

We suggest using the following names for the different types of media Applets:
NameType
audioAn audio streaming Applet
videoA video streaming Applet
whiteboardA whiteboard Applet
boardAnother name for a whiteboard Applet
presentationA slide show Applet
chatA chat line
consoleAn Applet providing a GUI to MASI features


As these names are only suggestions, you are not bound to them and you may develop other types of Applets, too. But you may take this table as a guide:
If, for example, you write a video streaming Applet, it might be a good idea to look for an Applet named "audio" before checking propietary names via getName() in order to find the one which delivers the audio portion of your content.

Warning:

To avoid interference, all MASI implementations must make sure that they are thread safe. The simplest way to do this, is to declare all implemented methods as synchronized.

Version:
1.00
Author:
Gerald Friedland, Lars Knipping, Ulli Raffel.
Date:
2001-07-24

Field Summary
static int CANBACKWARDOFFSET
          If you want to call backwardOffset(), getCapabilities() & CANBACKWARDOFFSET must be true.
static int CANCLOSE
          If you want to call close(), getCapabilities() & CANCLOSE must be true.
static int CANFORWARDOFFSET
          If you want to call forwardOffset(), getCapabilities() & CANFORWARDOFFSET must be true.
static int CANGETCHAPTEROFFSET
          If you want to call getChapterOffset(), getCapabilities() & CANGETCHAPTEROFFFSET must be true.
static int CANGETCURCHAPTER
          If you want to call getCurChapter(), getCapabilities() & CANGETCURCHAPTER must be true.
static int CANGETTOC
          If you want to call getTOC(), getCapabilities() & CANGETTOC must be true.
static int CANGETTOTALFRAMES
          If you want to call getTotalFrames(), getCapabilities() & CANGETTOTALFRAMES must be true.
static int CANPAUSE
          If you want to call pause(), getCapabilities() & CANPAUSE must be true.
static int CANREDOFROMSTART
          If you want to call redoFromStart(), getCapabilities() & CANREDOFROMSTART must be true.
static int CANSETOFFSET
          If you want to call setOffset(), getCapabilities() & CANSETOFFSET must be true.
static int MASIVERSION
          Contains the version of this interface multiplied by 100.
 
Method Summary
 long backwardOffset(long frames)
          Fast-backwards some frames.
 boolean close()
          Requests to close the whole Applet.
 java.lang.Object exchangeData(java.lang.Object o)
          This method can be used if two Applets want to exchange data in some way not specified by MASI.
 long forwardOffset(long frames)
          Fast-forwards some frames.
 java.util.Date getAbsoluteBeginningTime()
          Gets the absolute time when isInitFinished() could return true for the first time.
 int getCapabilities()
          Returns the capabilities of the Applet as integer.
 long getChapterOffset(int i)
          Returns the offset (in frames) where chapter number i starts.
 java.lang.String getCopyrightInformation()
          Returns copyright|left information.
 int getCurChapter()
          Returns the current chapter.
 double getFrameDurationMillis()
          Gets the length of one frame in milliseconds.
 long getFramesPerMilli()
          Provides the conversion between frames and milliseconds.
 java.lang.String getName()
          Gets the name of the Applet.
 long getOffset()
          Gets the current offset in frames.
 java.lang.String[] getTOC()
          Gets table of contents if available.
 long getTotalFrames()
          Gets the total length of this stream.
 int getVersion()
          Gets the version of Applet.
 boolean hasPermanentErrors()
          Returns true if the Applet has permanent errors.
 boolean isDestroyed()
          Is true when the Applet has been destroyed.
 boolean isFinished()
          Is true when an Applet has finished playing because the end of the stream has been reached.
 boolean isInitFinished()
          Returns true when the Applet has finished initialization and is working.
 boolean isPaused()
          Returns true if the Applet is paused.
 boolean isStalled()
          Returns true if the Applet has a bad connection to the Internet or some other problems at this moment.
 boolean isStopped()
          Is true when an Applet is in the stopped state.
 boolean pause(boolean onoff)
          Pauses or continues playing the stream.
 boolean redoFromStart()
          Reinitializes the Applet.
 long setOffset(long frame)
          Sets the current player position to frame.
 

Field Detail

MASIVERSION

public static final int MASIVERSION
Contains the version of this interface multiplied by 100. This is version 1.00.


CANBACKWARDOFFSET

public static final int CANBACKWARDOFFSET
If you want to call backwardOffset(), getCapabilities() & CANBACKWARDOFFSET must be true.

See Also:
backwardOffset(long)

CANFORWARDOFFSET

public static final int CANFORWARDOFFSET
If you want to call forwardOffset(), getCapabilities() & CANFORWARDOFFSET must be true.

See Also:
forwardOffset(long)

CANSETOFFSET

public static final int CANSETOFFSET
If you want to call setOffset(), getCapabilities() & CANSETOFFSET must be true.

See Also:
setOffset(long)

CANPAUSE

public static final int CANPAUSE
If you want to call pause(), getCapabilities() & CANPAUSE must be true.

See Also:
pause(boolean)

CANREDOFROMSTART

public static final int CANREDOFROMSTART
If you want to call redoFromStart(), getCapabilities() & CANREDOFROMSTART must be true.

See Also:
redoFromStart()

CANCLOSE

public static final int CANCLOSE
If you want to call close(), getCapabilities() & CANCLOSE must be true.

See Also:
close()

CANGETTOC

public static final int CANGETTOC
If you want to call getTOC(), getCapabilities() & CANGETTOC must be true.

See Also:
getTOC()

CANGETCHAPTEROFFSET

public static final int CANGETCHAPTEROFFSET
If you want to call getChapterOffset(), getCapabilities() & CANGETCHAPTEROFFFSET must be true.

See Also:
getChapterOffset(int)

CANGETCURCHAPTER

public static final int CANGETCURCHAPTER
If you want to call getCurChapter(), getCapabilities() & CANGETCURCHAPTER must be true.

See Also:
getCurChapter()

CANGETTOTALFRAMES

public static final int CANGETTOTALFRAMES
If you want to call getTotalFrames(), getCapabilities() & CANGETTOTALFRAMES must be true.

See Also:
getTotalFrames()
Method Detail

getCapabilities

public int getCapabilities()
Returns the capabilities of the Applet as integer. Each bit stands for one of the following methods:

BitMethodConstant
1backwardOffset()CANBACKWARDOFFSET
2forwardOffset()CANFORWARDOFFSET
3setOffset()CANSETOFFSET
4pause()CANPAUSE
5redoFromStart()CANREDOFROMSTART
6close()CANCLOSE
7getTOC()CANGETTOC
8getChapterOffset()CANGETCHAPTEROFFSET
9getCurChapter()CANGETCURCHAPTER
10getTotalFrames()CANGETTOTALFRAMES
11..32reserved for future use

You should only call a method if its bit is set. This does not touch other methods defined in this Interface
Please note that the settings may vary during execution of the Applet.

Returns:
an int containing the bitmask. You can use the constants defined above to access the bits.
See Also:
backwardOffset(long), forwardOffset(long), setOffset(long), pause(boolean), redoFromStart(), close(), getTOC(), getChapterOffset(int), getCurChapter(), getTotalFrames()

isInitFinished

public boolean isInitFinished()
Returns true when the Applet has finished initialization and is working. The Applet should only return true, when all connections are established, all buffers are filled, etc... and the Applet is ready to play or is already playing the content. Usually this would involve more steps than just having finished the Applet's init() method.

Returns:
false while initializing and true if the user is able to see the content. Once true it cannot switch back to false.

isStalled

public boolean isStalled()
Returns true if the Applet has a bad connection to the Internet or some other problems at this moment.

Returns:
true if the Applet has problems and the user is not able to see the media content at this moment
false is set again when Applet continues normal operation.

hasPermanentErrors

public boolean hasPermanentErrors()
Returns true if the Applet has permanent errors. Once true, the Applet can be ignored by the other Applets, because switching back to false is impossible.

Returns:
true if the Applet does not work.

isPaused

public boolean isPaused()
Returns true if the Applet is paused. Use pause(true) to get into this state.

Returns:
true while pausing.

isFinished

public boolean isFinished()
Is true when an Applet has finished playing because the end of the stream has been reached.

Returns:
true if the Applet has played the whole stream.

isStopped

public boolean isStopped()
Is true when an Applet is in the stopped state. An Applet is in the stopped state if the Applet's stop() method has been called or before the start() method is invoked. In an Applet that cannot be restarted isStopped() has the same semantic as the negation of Applet.isActive(). After being set to true once, the return value can switch back to false only if the Applet is restartable.

Returns:
a boolean value that indicates whether an Applet is in stopped state or not.
See Also:
isDestroyed()

isDestroyed

public boolean isDestroyed()
Is true when the Applet has been destroyed. An Applet is destroyed when the Applet's destroy() method has been called. Once an Applet is destroyed, it cannot be restarted. Therefore this value cannot switch from true to false. A return value of true also implies that the Applet is in the stopped state and therefore isStopped() also returns true.

Returns:
true if the Applet has been destroyed.
See Also:
isStopped()

getAbsoluteBeginningTime

public java.util.Date getAbsoluteBeginningTime()
Gets the absolute time when isInitFinished() could return true for the first time.

Returns:
the time when media content has begun to play as java.util.Date object.
See Also:
isInitFinished()

getOffset

public long getOffset()
Gets the current offset in frames.

Returns:
the current position in the stream.

getFramesPerMilli

public long getFramesPerMilli()
Provides the conversion between frames and milliseconds. Some applications, such as video, may need a more precise number than an integer number can represent. They should use getFrameDurationMillis(). Applets that want to indicate that a more precise number is required, should return 0 here.

Returns:
frames per millisecond.
See Also:
getFrameDurationMillis()

getFrameDurationMillis

public double getFrameDurationMillis()
Gets the length of one frame in milliseconds. The default method to obtain conversion betwwen frames and milliseconds is getFramesPerMilli(). This method can be used when a more precise number is required or it is better to calculate with milliseconds per frame instead of frames per milliseconds.

Returns:
a double value, which tries to be as exact as possible.
See Also:
getFramesPerMilli()

getName

public java.lang.String getName()
Gets the name of the Applet. An Applet should provide Name, Version, and Copyright or Copyleft information.

Returns:
a String containing the Applet's name.
See Also:
getVersion(), getCopyrightInformation()

getVersion

public int getVersion()
Gets the version of Applet.

Returns:
an int representation of the Applet's version number.
See Also:
getName(), getCopyrightInformation()

getCopyrightInformation

public java.lang.String getCopyrightInformation()
Returns copyright|left information.

Returns:
a String representation of the Applet's copyright|left information.
See Also:
getName(), getVersion()

getTotalFrames

public long getTotalFrames()
Gets the total length of this stream.

Returns:
the streamlength in frames if available. -1 if it is not available.

getTOC

public java.lang.String[] getTOC()
Gets table of contents if available. Returns an array of Strings indexed by chapter number. The Strings contain the chapter names. Chapter number 0 is reserved for the beginning of the file. If this feature is not supported by this Applet, null is returned. In fact, this feature needs to be supported only by one Applet per document.

Returns:
String[] - the array is indexed with the chapter number.
See Also:
CANGETTOC

getChapterOffset

public long getChapterOffset(int i)
Returns the offset (in frames) where chapter number i starts. This feature needs to be supported only by one Applet per content. We set getChapterOffset(0)=0. If i exceeds the amount of chapters in the document getChapterOffset(i) returns 0, too. 0 is also returned for negative values of i.

Parameters:
i - the chapter number
Returns:
the offset or -1 if feature is not supported by this Applet.
See Also:
CANGETCHAPTEROFFSET

getCurChapter

public int getCurChapter()
Returns the current chapter. This feature needs to be supported only by one Applet per content.

Returns:
the current chapter, or -1 if feature is not supported by this Applet.
See Also:
CANGETCURCHAPTER

setOffset

public long setOffset(long frame)
Sets the current player position to frame. Whenever possible use forwardOffset() and backwardOffset() to skip frames, because they can be implemented more efficiently sometimes.

Parameters:
frame - the new offset in the stream
Returns:
the current player position after the operation. Negative value for error.
See Also:
CANSETOFFSET, forwardOffset(long), backwardOffset(long)

forwardOffset

public long forwardOffset(long frames)
Fast-forwards some frames. Whenever possible, this method or backwardoffset() should be used instead of setOffset().

Parameters:
frames - a positive value indicating how many frames should be skipped from the current position of the stream.
Returns:
how many frames have been skipped. Negative value for error.
See Also:
CANFORWARDOFFSET, backwardOffset(long), setOffset(long)

backwardOffset

public long backwardOffset(long frames)
Fast-backwards some frames. Whenever possible, this method or forwardoffset() should be used instead of setOffset().

Parameters:
frames - a positive value indicating how many frames should skipped backwards from the current position of the stream.
Returns:
how many frames have been skipped. Negative value for error.
See Also:
CANBACKWARDOFFSET, forwardOffset(long), setOffset(long)

redoFromStart

public boolean redoFromStart()
Reinitializes the Applet. This causes the same behaviour as if the user would press the RELOAD button just for this Applet.

Returns:
true if the operation is allowed and the action is going to be executed.
See Also:
CANREDOFROMSTART

pause

public boolean pause(boolean onoff)
Pauses or continues playing the stream. If operation succeeds isPaused() will return true or false accordingly. Please notice, that pausing a stream may be a better method for synchronizing than setOffset(), because usually it can be implemented more efficiently.

Parameters:
true - for pause, false for continue
Returns:
true if operation was successful. Also true, if the call results in the status quo.
See Also:
CANPAUSE, CANSETOFFSET, isPaused(), setOffset(long)

exchangeData

public java.lang.Object exchangeData(java.lang.Object o)
This method can be used if two Applets want to exchange data in some way not specified by MASI. Please use this method only if you do not find another solution.

Parameters:
o - an Object
Returns:
a java.lang.Object

close

public boolean close()
Requests to close the whole Applet. This method provides a "soft way" to terminate a running MASI compliant Applet. In contrast to the destroy() method, the Applet has the choice to deny or accept the request. An Applet may or may not support this method properly, please check getCapabilities().

Returns:
true if the Applet has accepted the call and is going to destroy itself.
See Also:
getCapabilities(), CANCLOSE, isDestroyed(), isStopped()