📄 jmfapp-controller.html
字号:
</code><a name="90946"> </a><code> postEvent (new MediaTimeSetEvent (this, now));
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="90938"> </a><code> checkSegmentChange (now.getNanoseconds());
</code><a name="90939"> </a><code> }
</code><a name="90954"> </a><code>
</code><a name="90955"> </a><code> // We now need to spin a thread to compute/observe the
</code><a name="90956"> </a><code> // passage of time.
</code><a name="90957"> </a><code>
</code><a name="90958"> </a><code> public synchronized void syncStart (Time tbTime)
</code><a name="90959"> </a><code> {
</code><a name="90960"> </a><code> long startTime = ourClock.getMediaTime().getNanoseconds();
</code><a name="90961"> </a><code>
</code><a name="90962"> </a><code> // We may actually have to stop immediately with an
</code><a name="90963"> </a><code> // EndOfMediaEvent. We compute that now. If we are already
</code><a name="90964"> </a><code> // past end of media, then we
</code><a name="90965"> </a><code> // first post the StartEvent then we post a EndOfMediaEvent
</code><a name="90966"> </a><code>
</code><a name="90967"> </a><code> boolean endOfMedia;
</code><a name="90968"> </a><code> float rate = ourClock.getRate ();
</code><a name="90969"> </a><code>
</code><a name="90970"> </a><code> if ((startTime > duration && rate >= 0.0f) ||
</code><a name="90971"> </a><code> (startTime < 0 && rate <= 0.0f))
</code><a name="90972"> </a><code> {
</code><a name="90973"> </a><code> endOfMedia = true;
</code><a name="90974"> </a><code> }
</code><a name="90975"> </a><code>
</code><a name="90976"> </a><code> else
</code><a name="90977"> </a><code> {
</code><a name="90978"> </a><code> endOfMedia = false;
</code><a name="90979"> </a><code> }
</code><a name="90980"> </a><code>
</code><a name="90981"> </a><code> // We face the same possible problem with being past the stop
</code><a name="90982"> </a><code> // time. If so, we stop immediately.
</code><a name="90983"> </a><code>
</code><a name="90984"> </a><code> boolean pastStopTime;
</code><a name="90985"> </a><code> long stopTime = ourClock.getStopTime().getNanoseconds();
</code><a name="90986"> </a><code> if ((stopTime != Long.MAX_VALUE) &&
</code><a name="90987"> </a><code> ((startTime >= stopTime && rate >= 0.0f) ||
</code><a name="90988"> </a><code> (startTime <= stopTime && rate <= 0.0f)))
</code><a name="90989"> </a><code> {
</code><a name="90990"> </a><code> pastStopTime = true;
</code><a name="90991"> </a><code> }
</code><a name="90992"> </a><code>
</code><a name="90993"> </a><code> else
</code><a name="90994"> </a><code> {
</code><a name="90995"> </a><code> pastStopTime = false;
</code><a name="91001"> </a><code> }
</code><a name="91002"> </a><code>
</code><a name="91003"> </a><code> if (!endOfMedia && !pastStopTime)
</code><a name="91004"> </a><code> {
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91016"> </a><code> ourClock.syncStart (tbTime);
</code><a name="91022"> </a><code> ourState = Controller.Started;
</code><a name="91023"> </a><code> }
</code><a name="91024"> </a><code>
</code><a name="91025"> </a><code> postEvent (new StartEvent (this, Controller.Prefetched,
</code><a name="91026"> </a><code> Controller.Started, Controller.Started,
</code><a name="91027"> </a><code> new Time(startTime), tbTime));
</code><a name="91028"> </a><code>
</code><a name="91029"> </a><code> if (endOfMedia)
</code><a name="91030"> </a><code> {
</code><a name="91031"> </a><code> postEvent (new EndOfMediaEvent (this,
</code><a name="91032"> </a><code> Controller.Started,
</code><a name="91033"> </a><code> Controller.Prefetched, Controller.Prefetched,
</code><a name="91034"> </a><code> new Time(startTime)));
</code><a name="91035"> </a><code> }
</code><a name="91036"> </a><code>
</code><a name="91037"> </a><code> else if (pastStopTime)
</code><a name="91038"> </a><code> {
</code><a name="91039"> </a><code> postEvent (new StopAtTimeEvent (this, Controller.Started,
</code><a name="91040"> </a><code> Controller.Prefetched, Controller.Prefetched,
</code><a name="91041"> </a><code> new Time(startTime)));
</code><a name="91042"> </a><code> }
</code><a name="91043"> </a><code>
</code><a name="91044"> </a><code> else
</code><a name="91045"> </a><code> {
</code><a name="91046"> </a><code> myThread = new Thread (this, "TimeLineController");
</code><a name="91047"> </a><code>
</code><a name="91048"> </a><code> // Set thread to appopriate priority...
</code><a name="91049"> </a><code> myThread.start ();
</code><a name="91050"> </a><code> }
</code><a name="91051"> </a><code> }
</code><a name="91052"> </a><code>
</code><a name="91053"> </a><code>
</code><a name="91054"> </a><code>
</code><a name="91055"> </a><code> // Nothing really special here except that we need to notify
</code><a name="91056"> </a><code> // the thread that we may have.
</code><a name="91057"> </a><code>
</code><a name="91058"> </a><code> public synchronized void setStopTime (Time stopTime)
</code><a name="91059"> </a><code> {
</code><a name="91060"> </a><code> ourClock.setStopTime (stopTime);
</code><a name="91061"> </a><code> postEvent (new StopTimeChangeEvent (this, stopTime));
</code><a name="91062"> </a><code> notifyAll ();
</code><a name="91063"> </a><code> }
</code><a name="91064"> </a><code>
</code><a name="91065"> </a><code> // This one is also pretty easy. We stop and tell the running
</code><a name="91066"> </a><code> // thread to exit.
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91080"> </a><code> public synchronized void stop ()
</code><a name="91081"> </a><code> {
</code><a name="91082"> </a><code> int previousState = ourState;
</code><a name="91083"> </a><code> ourClock.stop ();
</code><a name="91084"> </a><code> ourState = Controller.Prefetched;
</code><a name="91085"> </a><code> postEvent (new StopByRequestEvent (this, previousState,
</code><a name="91086"> </a><code> Controller.Prefetched, Controller.Prefetched,
</code><a name="91087"> </a><code> ourClock.getMediaTime ()));
</code><a name="91088"> </a><code> notifyAll ();
</code><a name="91089"> </a><code>
</code><a name="91090"> </a><code> // Wait for thread to shut down.
</code><a name="91091"> </a><code>
</code><a name="91092"> </a><code> while (myThread != null)
</code><a name="91093"> </a><code> {
</code><a name="91094"> </a><code> try
</code><a name="91095"> </a><code> {
</code><a name="91096"> </a><code> wait ();
</code><a name="91097"> </a><code> }
</code><a name="91098"> </a><code> catch (InterruptedException e)
</code><a name="91099"> </a><code> {
</code><a name="91100"> </a><code> // NOT REACHED
</code><a name="91101"> </a><code> }
</code><a name="91102"> </a><code> }
</code><a name="91103"> </a><code> }
</code><a name="91104"> </a><code>
</code><a name="91105"> </a><code> protected void checkSegmentChange (long timeNow)
</code><a name="91106"> </a><code> {
</code><a name="91107"> </a><code> int segment = computeSegment (timeNow);
</code><a name="91108"> </a><code> if (segment != currentSegment)
</code><a name="91109"> </a><code> {
</code><a name="91110"> </a><code> currentSegment = segment;
</code><a name="91111"> </a><code> postEvent (new TimeLineEvent (this, currentSegment));
</code><a name="91112"> </a><code> }
</code><a name="91113"> </a><code> }
</code><a name="91114"> </a><code>
</code><a name="91115"> </a><code> // Most of the real work goes here. We have to decide when
</code><a name="91116"> </a><code> // to post events like EndOfMediaEvent and StopAtTimeEvent
</code><a name="91117"> </a><code> // and TimeLineEvent.
</code><a name="91123"> </a><code>
</code><a name="91124"> </a><code> public synchronized void run ()
</code><a name="91125"> </a><code> {
</code><a name="91126"> </a><code> long timeToNextSegment = 0;
</code><a name="91127"> </a><code> long mediaTimeToWait = 0;
</code><a name="91133"> </a><code>
</code><a name="91134"> </a><code> float ourRate = 1.0f;
</code><a name="91076"> </a><code>
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91140"> </a><code> for (;;)
</code><a name="91141"> </a><code> {
</code><a name="91142"> </a><code> // First, have we changed segments? If so, post an event!
</code><a name="91143"> </a><code>
</code><a name="91144"> </a><code> long timeNow = ourClock.getMediaTime ().getNanoseconds ();
</code><a name="91145"> </a><code> checkSegmentChange (timeNow);
</code><a name="91146"> </a><code>
</code><a name="91147"> </a><code> // Second, have we already been stopped? If so, stop
</code><a name="91148"> </a><code> // the thread.
</code><a name="91149"> </a><code>
</code><a name="91150"> </a><code> if (ourState == Controller.Prefetched)
</code><a name="91151"> </a><code> {
</code><a name="91152"> </a><code> myThread = null;
</code><a name="91153"> </a><code>
</code><a name="91154"> </a><code> // If someone is waiting for the thread to die, let them
</code><a name="91155"> </a><code> // know.
</code><a name="91156"> </a><code>
</code><a name="91157"> </a><code> notifyAll ();
</code><a name="91158"> </a><code> break;
</code><a name="91159"> </a><code> }
</code><a name="91160"> </a><code>
</code><a name="91161"> </a><code> // Current rate. Our setRate() method prevents the value
</code><a name="91162"> </a><code> // 0 so we don't check for that here.
</code><a name="91163"> </a><code>
</code><a name="91164"> </a><code> ourRate = ourClock.getRate ();
</code><a name="91165"> </a><code>
</code><a name="91166"> </a><code> // How long in clock time do we need to wait before doing
</code><a name="91167"> </a><code> // something?
</code><a name="91168"> </a><code>
</code><a name="91169"> </a><code> long endOfMediaTime;
</code><a name="91170"> </a><code>
</code><a name="91171"> </a><code> // Next, are we past end of media?
</code><a name="91172"> </a><code>
</code><a name="91173"> </a><code> if (ourRate > 0.0f)
</code><a name="91174"> </a><code> {
</code><a name="91175"> </a><code> mediaTimeToWait = duration - timeNow;
</code><a name="91176"> </a><code> endOfMediaTime = duration;
</code><a name="91177"> </a><code> }
</code><a name="91178"> </a><code> else
</code><a name="91179"> </a><code> {
</code><a name="91180"> </a><code> mediaTimeToWait = timeNow;
</code><a name="91181"> </a><code> endOfMediaTime = 0;
</code><a name="91182"> </a><code> }
</code><a name="91188"> </a><code>
</code><a name="91189"> </a><code> // If we are at (or past) time to stop due to EndOfMedia,
</code><a name="91190"> </a><code> // we do that now!
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91208"> </a><code> if (mediaTimeToWait <= 0)
</code><a name="91209"> </a><code> {
</code><a name="91210"> </a><code> ourClock.stop ();
</code><a name="91216"> </a><code> ourClock.setMediaTime (new Time(endOfMediaTime));
</code><a name="91217"> </a><code> ourState = Controller.Prefetched;
</code><a name="91218"> </a><code> postEvent (new EndOfMediaEvent (this, Controller.Started,
</code><a name="91219"> </a><code> Controller.Prefetched, Controller.Prefetched,
</code><a name="91220"> </a><code> new Time(endOfMediaTime)));
</code><a name="91221"> </a><code> continue;
</code><a name="91222"> </a><code> }
</code><a name="91223"> </a><code>
</code><a name="91224"> </a><code> // How long until we hit our stop time?
</code><a name="91225"> </a><code>
</code><a name="91226"> </a><code> long stopTime = ourClock.getStopTime ().getNanoseconds();
</code><a name="91227"> </a><code> if (stopTime != Long.MAX_VALUE)
</code><a name="91228"> </a><code> {
</code><a name="91229"> </a><code> long timeToStop;
</code><a name="91230"> </a><code> if (ourRate > 0.0f)
</code><a name="91231"> </a><code> {
</code><a name="91232"> </a><code> timeToStop = stopTime - timeNow;
</code><a name="91233"> </a><code> }
</code><a name="91234"> </a><code> else
</code><a name="91235"> </a><code> {
</code><a name="91236"> </a><code> timeToStop = timeNow - stopTime;
</code><a name="91237"> </a><code> }
</code><a name="91238"> </a><code>
</code><a name="91239"> </a><code> // If we are at (or past) time to stop due to the stop
</code><a name="91240"> </a><code> // time, we stop now!
</code><a name="91241"> </a><code> if (timeToStop <= 0)
</code><a name="91242"> </a><code> {
</code><a name="91243"> </a><code> ourClock.stop ();
</code><a name="91244"> </a><code> ourClock.setMediaTime (new Time(stopTime));
</code><a name="91245"> </a><code> ourState = Controller.Prefetched;
</code><a name="91246"> </a><code> postEvent (new StopAtTimeEvent (this,
Controller.Started,
</code><a name="91247"> </a><code> Controller.Prefetched, Controller.Prefetched,
</code><a name="91248"> </a><code> new Time(stopTime)));
</code><a name="91249"> </a><code> continue;
</code><a name="91250"> </a><code> }
</code><a name="91251"> </a><code> else if (timeToStop < mediaTimeToWait)
</code><a name="91252"> </a><code> {
</code><a name="91253"> </a><code> mediaTimeToWait = timeToStop;
</code><a name="91254"> </a><code> }
</code><a name="91255"> </a><code> }
</code></pre>
</font></td>
</tr>
<tr>
<td><font face="Palatino, Times New Roman, Times, serif"><pre>
<a name="91276"> </a><code> // How long until we pass into the next time line segment?
</code><a name="91277"> </a><code>
</code><a name="91278"> </a><code> if (ourRate > 0.0f)
</code><a name="91284"> </a><code> {
</code><a name="91285"> </a><code> timeToNextSegment = timeLine[currentSegment] - timeNow;
</code><a name="91286"> </a><code> }
</code><a name="91287"> </a><code>
</code><a name="91288"> </a><code> else if (currentSegment == 0)
</code><a name="91289"> </a><code> {
</code><a name="91290"> </a><code> timeToNextSegment = timeNow;
</code><a name="91291"> </a><code> }
</code><a name="91292"> </a><code>
</code><a name="91293"> </a><code> else
</code><a name="91294"> </a><code> {
</code><a name="91295"> </a><code> timeToNextSegment = timeNow - timeLine[currentSegment-1];
</code><a name="91296"> </a><code> }
</code><a name="91297"> </a><code> }
</code><a name="91298"> </a><code>
</code><a name="91299"> </a><code> if (timeToNextSegment < mediaTimeToWait)
</code><a name="91300"> </a><code> {
</code><a name="91301"> </a><code> mediaTimeToWait = timeToNextSegment;
</code><a name="91302"> </a><code> }
</code><a name="91303"> </a><code>
</code><a name="91304"> </a><code> // Do the ugly math to compute what value to pass to
</code><a name="91305"> </a><code> // wait():
</code><a name="91306"> </a><code>
</code><a name="91307"> </a><code> long waitTime;
</code><a name="91308"> </a><code> if (ourRate > 0)
</code><a name="91309"> </a><code> {
</code><a name="91310"> </a><code> waitTime = (long) ((float) mediaTimeToWait / ourRate) /
</code><a name="91311"> </a><code> 1000000;
</code><a name="91312"> </a><code> }
</code><a name="91313"> </a><code> else
</code><a name="91314"> </a><code> {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -