📄 jmfpresenting.html
字号:
<p>
<a name="99750"> </a><font face="Palatino, Times New Roman, Times, serif">You can get a <code>Player </code>object's current time-base time by getting the <code>Player </code>object's <code>TimeBase</code> and calling <code>getTime</code>:</font>
</p>
<pre>
<a name="99752"> </a><code>myCurrentTBTime = player1.getTimeBase().getTime();
</code></pre>
<p>
<a name="94519"> </a><font face="Palatino, Times New Roman, Times, serif">When a <code>Player</code> is running, you can get the time-base time that corresponds to a particular media time by calling <code>mapToTimeBase</code>. </font>
</p>
<h4>
<a name="93867"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Getting the Duration of the Media Stream</font>
</h4>
<p>
<a name="101776"> </a><font face="Palatino, Times New Roman, Times, serif">Since programs often need to know how long a particular media stream will run, all <code>Controllers</code> implement the <code>Duration</code> interface. This interface defines a single method, <code>getDuration</code>. The duration represents the length of time that a media object would run, if played at the default rate of 1.0. A media stream's duration is only accessible through a <code>Player</code>. </font>
</p>
<p>
<a name="101778"> </a><font face="Palatino, Times New Roman, Times, serif">If the duration can't be determined when <code>getDuration</code> is called, <code>DURATION_UNKNOWN</code> is returned. This can happen if the <code>Player</code> has not yet reached a state where the duration of the media source is available. At a later time, the duration might be available and a call to <code>getDuration</code> would return the duration value. If the media source does not have a defined duration, as in the case of a live broadcast, <code>getDuration</code> returns <code>DURATION_UNBOUNDED</code>. </font>
</p>
<h3>
<a name="94440"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Responding to Media Events</font>
</h3>
<p>
<a name="94441"> </a><font face="Palatino, Times New Roman, Times, serif"><code>ControllerListener</code> is an asynchronous interface for handling events generated by <code>Controller</code> objects. Using the <code>ControllerListener</code> interface enables you to manage the timing of potentially time-consuming <code>Player</code> operations such as prefetching. </font>
</p>
<h4>
<a name="94442"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Implementing the ControllerListener Interface</font>
</h4>
<p>
<a name="94452"> </a><font face="Palatino, Times New Roman, Times, serif">To implement the <code>ControllerListener</code> interface, you need to:</font>
</p>
<ol type="1">
<li value="1"><a name="94453"> </a><font face="Palatino, Times New Roman, Times, serif">Implement the <code>ControllerListener</code> interface in a class.</font>
<li value="2"><a name="94455"> </a><font face="Palatino, Times New Roman, Times, serif">Register that class as a listener by calling <code>addControllerListener</code> on the <code>Controller</code> that you want to receive events from.</font>
</ol>
<p>
<a name="94457"> </a><font face="Palatino, Times New Roman, Times, serif">When a <code>Controller</code> posts an event, it calls <code>controllerUpdate</code> on each registered listener. </font>
</p>
<p>
<a name="98180"> </a><font face="Palatino, Times New Roman, Times, serif">Typically, <code>controllerUpdate</code> is implemented as a series of if-else statements.</font>
</p>
<a name="100676"> </a><font size="1" face="Palatino, Times New Roman, Times, serif">
<table border="1" bordercolorlight="#FFFFFF" bordercolordark="#000000"
cellpadding="5" cellspacing="0">
<caption><b><i><font face="Palatino, Times New Roman, Times, serif"><a name="100679"> </a>Example 3-3: Implementing controllerUpdate.</font></i></b></caption>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="100683"> </a>if (event instanceof EventType){
<a name="100684"> </a>...
<a name="100685"> </a>} else if (event instanceof OtherEventType){
<a name="100686"> </a>...
<a name="100687"> </a>}
</pre>
</font></td>
</tr>
</table>
<br></font>
<p>
<a name="94463"> </a><font face="Palatino, Times New Roman, Times, serif">This filters out the events that you are not interested in. If you have registered as a listener with multiple <code>Controllers</code>, you also need to determine which <code>Controller</code> posted the event. <code>ControllerEvents</code> come "stamped" with a reference to their source that you can access by calling <code>getSource</code>.</font>
</p>
<p>
<a name="94469"> </a><font face="Palatino, Times New Roman, Times, serif">When you receive events from a <code>Controller</code>, you might need to do some additional processing to ensure that the <code>Controller</code> is in the proper state before calling a control method. For example, before calling any of the methods that are restricted to <em>Stopped</em> <code>Players</code>, you should check the <code>Player</code> object's target state by calling <code>getTargetState</code>. If <code>start</code> has been called, the <code>Player</code> is considered to be in the <em>Started</em> state, though it might be posting transition events as it prepares the <code>Player</code> to present media.</font>
</p>
<p>
<a name="94471"> </a><font face="Palatino, Times New Roman, Times, serif">Some types of <code>ControllerEvents</code> contain additional state information. For example, the <code>StartEvent</code> and <code>StopEvent</code> classes each define a method that allows you to retrieve the media time at which the event occurred.</font>
</p>
<h4>
<a name="93870"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Using ControllerAdapter</font>
</h4>
<p>
<a name="96156"> </a><font face="Palatino, Times New Roman, Times, serif"><code>ControllerAdapter</code> is a convenience class that implements <code>ControllerListener</code> and can be easily extended to respond to particular <code>Events</code>. To implement the <code>ControllerListener </code>interface using<code> ControllerAdapter</code>, you need to:</font>
</p>
<ol type="1">
<li value="1"><a name="95757"> </a><font face="Palatino, Times New Roman, Times, serif">Subclass <code>ControllerAdapter</code> and override the event methods for the events that you're interested in. </font>
<li value="2"><a name="95758"> </a><font face="Palatino, Times New Roman, Times, serif">Register your <code>ControllerAdapter</code> class as a listener for a particular <code>Controller</code> by calling <code>addControllerListener</code>.</font>
</ol>
<p>
<a name="95760"> </a><font face="Palatino, Times New Roman, Times, serif">When a <code>Controller</code> posts an event, it calls <code>controllerUpdate</code> on each registered listener. <code>ControllerAdapter</code> automatically dispatches the event to the appropriate event method, filtering out the events that you're not interested in.</font>
</p>
<p>
<a name="95761"> </a><font face="Palatino, Times New Roman, Times, serif">For example, the following code extends a <code>ControllerAdapter</code> with a JDK 1.1 anonymous inner-class to create a self-contained <code>Player</code> that is automatically reset to the beginning of the media and deallocated when the <code>Player</code> reaches the end of the media.</font>
</p>
<a name="100705"> </a><font size="1" face="Palatino, Times New Roman, Times, serif">
<table border="1" bordercolorlight="#FFFFFF" bordercolordark="#000000"
cellpadding="5" cellspacing="0">
<caption><b><i><font face="Palatino, Times New Roman, Times, serif"><a name="100708"> </a>Example 3-4: Using ControllerAdapter.</font></i></b></caption>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="100712"> </a><code>player.addControllerListener(new ControllerAdapter() {
</code><a name="100713"> </a><code> public void endOfMedia(EndOfMediaEvent e) {
</code><a name="100714"> </a><code> Controller controller = e.getSource();
</code><a name="100715"> </a><code> controller.stop();
</code><a name="100716"> </a><code> controller.setMediaTime(new Time(0));
</code><a name="100717"> </a><code> controller.deallocate();
</code><a name="100718"> </a><code> }
</code><a name="100719"> </a><code>})
</code></pre>
</font></td>
</tr>
</table>
<br></font>
<p>
<a name="95770"> </a><font face="Palatino, Times New Roman, Times, serif">If you register a single <code>ControllerAdapter</code> as a listener for multiple <code>Players</code>, in your event method implementations you need to determine which <code>Player</code> generated the event. You can call <code>getSource</code> to determine where a <code>ControllerEvent</code> originated. </font>
</p>
<h3>
<a name="94786"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Synchronizing Multiple Media Streams</font>
</h3>
<p>
<a name="94568"> </a><font face="Palatino, Times New Roman, Times, serif">To synchronize the playback of multiple media streams, you can synchronize the <code>Players</code> by associating them with the same <code>TimeBase</code>. To do this, you use the <code>getTimeBase</code> and <code>setTimeBase</code> methods defined by the <code>Clock</code> interface. For example, you could synchronize <code>player1</code> with <code>player2</code> by setting <code>player1</code> to use <code>player2's</code> time base: </font>
</p>
<pre>
<a name="94572"> </a><code>player1.setTimeBase(player2.getTimeBase());
</code></pre>
<p>
<a name="94573"> </a><font face="Palatino, Times New Roman, Times, serif">When you synchronize <code>Players</code> by associating them with the same <code>TimeBase</code>, you must still manage the control of each <code>Player</code> individually. Because managing synchronized <code>Players</code> in this way can be complicated, JMF provides a mechanism that allows a <code>Player</code> to assume control over any other <code>Controller</code>. The <code>Player</code> manages the states of these <code>Controllers</code> automatically, allowing you to interact with the entire group through a single point of control. For more information, see <a href="JMFPresenting.html#93873">See "Using a Player to Synchronize Controllers"</a>.</font>
</p>
<h4>
<a name="93873"> </a><font color="#003366" face="Palatino, Times New Roman, Times, serif">Using a Player to Synchronize Controllers</font>
</h4>
<p>
<a name="94617"> </a><font face="Palatino, Times New Roman, Times, serif">Synchronizing <code>Players</code> directly using <code>syncStart</code> requires that you carefully manage the states of all of the synchronized <code>Players</code>. You must control each one individually, listening for events and calling control methods on them as appropriate. Even with only a few <code>Players</code>, this quickly becomes a difficult task. Through the <code>Player</code> interface, JMF provides a simpler solution: a <code>Player</code> can be used to manage the operation of any <code>Controller</code>. </font>
</p>
<p>
<a name="94618"> </a><font face="Palatino, Times New Roman, Times, serif">When you interact with a managing <code>Player</code>, your instructions are automatically passed along to the managed <code>Controllers</code> as appropriate. The managing <code>Player</code> takes care of the state management and synchronization for all of the other <code>Controllers</code>.</font>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -