PlayerRunnerThread.java
上传用户:liming6160
上传日期:2022-06-07
资源大小:785k
文件大小:12k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  *    Copyright (C) 2001 - 2007 Mobicom-Kavkaz, Inc
  3.  *    MFRadio - stream radio client for Java 2 Micro Edition
  4.  *    
  5.  *    Visit the project page at: http://mfradio.sourceforge.net
  6.  *
  7.  *    This program is free software; you can redistribute it and/or modify
  8.  *    it under the terms of the GNU General Public License as published by
  9.  *    the Free Software Foundation; either version 2 of the License, or
  10.  *    (at your option) any later version.
  11.  *
  12.  *    This program is distributed in the hope that it will be useful,
  13.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *    GNU General Public License for more details.
  16.  *
  17.  *    You should have received a copy of the GNU General Public License
  18.  *    along with this program; if not, write to the Free Software
  19.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *    Java (TM) and all Java (TM)-based marks are a trademark or 
  22.  *    registered trademark of Sun Microsystems, Inc, in the United States 
  23.  *    and other countries.
  24.  */
  25. package ru.mobicomk.mfradio.controller;
  26. import javax.microedition.media.MediaException;
  27. import javax.microedition.media.Player;
  28. import javax.microedition.media.PlayerListener;
  29. import javax.microedition.media.control.VolumeControl;
  30. import ru.mobicomk.mfradio.iface.PlayerQueue;
  31. import ru.mobicomk.mfradio.util.BooleanFlag;
  32. import ru.mobicomk.mfradio.util.PlayerQueueException;
  33. /**
  34.  * Player runner thread.
  35.  * <p>
  36.  * Gets next Player object from Player's queue and starts it.
  37.  * </p>
  38.  * 
  39.  * @author Roman Bondarenko
  40.  * @see UIController
  41.  * @see PlayerQueue
  42.  */
  43. class PlayerRunnerThread extends Thread implements PlayerListener {
  44.     /**
  45.          * Controller must setting up this flag to <b>true</b> for stop thread
  46.          * execution.
  47.          */
  48.     BooleanFlag StopFlag;
  49.     private UIController controller_;
  50.     private PlayerQueue queue_;
  51.     private Object playerSync_;
  52.     private Object player2Sync_;
  53.     private Player player0_ = null;
  54.     private Player player1_ = null;
  55.     private PlayerListener listener_ = null;
  56.     /**
  57.          * Creates a new instance of PlayerRunnerThread.
  58.          * 
  59.          * @param queue
  60.          *                Player queue object.
  61.          * @param controller
  62.          *                Application controller object.
  63.          */
  64.     PlayerRunnerThread(PlayerQueue queue, UIController controller) {
  65. controller_ = controller;
  66. queue_ = queue;
  67. StopFlag = new BooleanFlag(false);
  68. playerSync_ = new Object();
  69. player2Sync_ = new Object();
  70.     }
  71.     /**
  72.          * Set the volume using linear point scale with values between 0 and
  73.          * 100. 0 is silence; 100 is the loudest usefull level that current
  74.          * VolumeControl supports. If the given level is less than 0 or greater
  75.          * than 100, the level well be set to 0 or 100 respectively.
  76.          * 
  77.          * @param volume
  78.          *                The new volume specified in the level scale.
  79.          */
  80.     void setVolume(int volume) {
  81. if (player1_ != null) {
  82.     if (player1_.getState() == Player.STARTED) {
  83. VolumeControl vc = (VolumeControl) player1_
  84. .getControl("VolumeControl");
  85. if (vc != null) {
  86.     vc.setLevel(volume);
  87. }
  88.     }
  89. }
  90.     }
  91.     /**
  92.          * Stop execution thread helper.
  93.          */
  94.     void stop() {
  95. StopFlag.set();
  96. synchronized (playerSync_) {
  97.     playerSync_.notify();
  98. }
  99.     }
  100.     /**
  101.          * Connect player listener object to this player runner thread. Supports
  102.          * only once listener at a time.
  103.          * <p>
  104.          * <b>Note:</b> Old listener disconnects without any notifications if
  105.          * new object was connected.
  106.          * </p>
  107.          * 
  108.          * @param listener
  109.          *                Player listener object.
  110.          */
  111.     void setPlayerListener(PlayerListener listener) {
  112. listener_ = listener;
  113.     }
  114.     // Runnable interface
  115.         // //////////////////////////////////////////////////////
  116.     /**
  117.          * Thread entry point.
  118.          * 
  119.          * @see java.lang.Thread
  120.          * @see java.lang.Thread#run
  121.          */
  122.     public void run() {
  123. try {
  124.     /*
  125.                  * long duration = player1_.getDuration();
  126.                  * 
  127.                  * if (duration != Player.TIME_UNKNOWN) { durationSwitchLoop(); }
  128.                  * else { eosSwitchLoop(); }
  129.                  */
  130.     switchLoop();
  131. } catch (InterruptedException ex) {
  132.     ex.printStackTrace();
  133.     // StopFlag.set();
  134. } catch (PlayerQueueException ex) {
  135.     ex.printStackTrace();
  136.     StopFlag.set();
  137. } catch (MediaException ex) {
  138.     ex.printStackTrace();
  139. } finally {
  140.     closePlayer(player1_);
  141.     closePlayer(player0_);
  142. }
  143. if (!StopFlag.value()) {
  144.     StopFlag.set();
  145.     controller_.runnerIsInterrupted();
  146. } else {
  147.     controller_.runnerIsStopped();
  148. }
  149. // controller_.log("runner >> finish thread");
  150.     }
  151.     /**
  152.          * {@link PlayerListener} interface implementation method.
  153.          * 
  154.          * @param player
  155.          *                The player which generated this event.
  156.          * @param event
  157.          *                The event generated as defined by the enumerated
  158.          *                types.
  159.          * @param object
  160.          *                The associated event data.
  161.          * @see javax.microedition.media.PlayerListener interface.
  162.          */
  163.     public void playerUpdate(Player player, String event, Object object) {
  164. if (event == PlayerListener.END_OF_MEDIA) {
  165.     boolean err = false;
  166.     if (player0_ != null) {
  167. synchronized (player2Sync_) {
  168.     VolumeControl volume = (VolumeControl) player0_
  169.     .getControl("VolumeControl");
  170.     if (volume != null) {
  171. volume.setLevel(controller_.getVolume());// !!
  172.     }
  173.     try {
  174. player0_.start();
  175. // controller_.log("upd >>
  176.                         // "+System.currentTimeMillis()+" >> start player");
  177.     } catch (MediaException ex) {
  178. err = true;
  179.     }
  180.     player1_.close();
  181.     player1_ = err ? null : player0_;
  182.     if (err) {
  183. player0_.close();
  184. // controller_.log("upd >>
  185.                         // "+System.currentTimeMillis()+" >> close player");
  186.     }
  187.     player0_ = null;
  188. }
  189. synchronized (playerSync_) {
  190.     playerSync_.notify();
  191. }
  192.     } else {
  193. player1_.close();
  194. player1_ = null;
  195. // controller_.log("upd >> "+System.currentTimeMillis()+" >>
  196.                 // close player; no more players.");
  197.     }
  198. }
  199.     }
  200.     // Privates
  201.         // ////////////////////////////////////////////////////////////////
  202.     private void closePlayer(Player player) {
  203. if (player == null || player.getState() == Player.CLOSED) {
  204.     return;
  205. }
  206. try {
  207.     player.stop();
  208. } catch (MediaException e) {
  209. }
  210. player.close();
  211. player = null;
  212.     }
  213.     private void switchLoop() throws PlayerQueueException,
  214.     InterruptedException, MediaException {
  215. player1_ = null;
  216. while (!StopFlag.value()) {
  217.     // controller_.log("eos >> "+System.currentTimeMillis()+" >>
  218.                 // wait for next player");
  219.     player0_ = queue_.popHead(); // exception
  220.     // controller_.log("eos >> "+System.currentTimeMillis()+" >>
  221.                 // next player! duration: " + player0_.getDuration()/1000);
  222.     if (player1_ == null && player0_ != null) {
  223. synchronized (player2Sync_) {
  224.     VolumeControl volume = (VolumeControl) player0_
  225.     .getControl("VolumeControl");
  226.     if (volume != null) {
  227. volume.setLevel(controller_.getVolume());// !!
  228.     }
  229.     player0_.start();
  230.     player1_ = player0_;
  231.     player0_ = null;
  232.     // controller_.log("eos >>
  233.                         // "+System.currentTimeMillis()+" >> start player");
  234. }
  235.     } else {
  236. synchronized (playerSync_) {
  237.     // controller_.log("eos >>
  238.                         // "+System.currentTimeMillis()+" >> wait for EOS");
  239.     playerSync_.wait(/* player0_.getDuration()/1000 + 1000 */);
  240. }
  241.     }
  242. }
  243.     }
  244.     // //////////////////////////////////////////////////////////////////////////
  245.     // 
  246.     // Other method
  247.     //
  248.     // //////////////////////////////////////////////////////////////////////////
  249.     /*
  250.          * private void eosSwitchLoop() throws PlayerQueueException,
  251.          * InterruptedException, MediaException { doNotWait_ = true; while
  252.          * (!StopFlag.value()) { player0_ = queue_.popHead();
  253.          * //controller_.log("eos >> "+System.currentTimeMillis()+" >> next
  254.          * player");
  255.          * 
  256.          * if (doNotWait_) { VolumeControl volume =
  257.          * (VolumeControl)player0_.getControl("VolumeControl"); if (volume !=
  258.          * null) { volume.setLevel(controller_.getVolume());// !! }
  259.          * player0_.start(); //controller_.log("eos >>
  260.          * "+System.currentTimeMillis()+" >> start player"); doNotWait_ = false; }
  261.          * else { synchronized (playerSync_) { //controller_.log("eos >>
  262.          * "+System.currentTimeMillis()+" >> wait for EOS"); playerSync_.wait(); } } } }
  263.          *  // PlayerListener interface
  264.          * ////////////////////////////////////////////////
  265.          * 
  266.          * public void playerUpdate(Player player, String event, Object object) {
  267.          * 
  268.          * if(event == PlayerListener.STOPPED){ player1_ = null; player.close();
  269.          * //controller_.log("upd >> "+System.currentTimeMillis()+" >> STOPPED
  270.          * for " + player.toString()); return; }
  271.          * 
  272.          * if (event == PlayerListener.STARTED) { //controller_.log("upd >>
  273.          * "+System.currentTimeMillis()+" >> STARTED for " + player.toString());
  274.          * //volume_ = null; player0_ = null; player1_ = player; synchronized
  275.          * (playerSync_) { playerSync_.notify(); } return; }
  276.          * 
  277.          * if(event == PlayerListener.END_OF_MEDIA){ //controller_.log("upd >>
  278.          * "+System.currentTimeMillis()+" >> EOS for " + player.toString());
  279.          * 
  280.          * if (StopFlag.value()) { //controller_.log("upd >>
  281.          * "+System.currentTimeMillis()+" >> Stop flag!"); return; //?? }
  282.          * 
  283.          * VolumeControl volume =
  284.          * (VolumeControl)player0_.getControl("VolumeControl"); if (volume !=
  285.          * null) { volume.setLevel(controller_.getVolume());// !! }
  286.          * 
  287.          * if (player0_ != null) { try { player0_.start();
  288.          * //controller_.log("upd >> "+System.currentTimeMillis()+" >> start
  289.          * player " + player0_.toString()); } catch (MediaException ex) {
  290.          * //controller_.log("upd >> "+System.currentTimeMillis()+" >>
  291.          * "+ex.toString()+"; set doNotWait flag."); doNotWait_ = true; } } else {
  292.          * //controller_.log("upd >> "+System.currentTimeMillis()+" >> player0
  293.          * is null! set doNotWait flag."); doNotWait_ = true; }
  294.          * 
  295.          * //try { //player.stop(); //} catch (MediaException ex) { }
  296.          * player.close(); //controller_.log("upd >>
  297.          * "+System.currentTimeMillis()+" >> close player " +
  298.          * player.toString()); //player1_ = null; } }
  299.          * 
  300.          * private void durationSwitchLoop() { while (!StopFlag.value()) { try {
  301.          * player0_ = queue_.popHead(); sleep(player1_.getDuration() / 1000 -
  302.          * 50);
  303.          * 
  304.          * if (StopFlag.value()) { break; }
  305.          * 
  306.          * VolumeControl volume =
  307.          * (VolumeControl)player0_.getControl("VolumeControl"); if (volume !=
  308.          * null) { volume.setLevel(controller_.getVolume());// !! }
  309.          * player0_.start(); player1_ = player0_;
  310.          *  } catch (PlayerQueueException ex) { break; // stop execution thread } } }
  311.          * 
  312.          * public void playerUpdate(Player player, String event, Object object) {
  313.          * if(event == PlayerListener.STOPPED){ player.close(); return; }
  314.          * 
  315.          * if(event == PlayerListener.END_OF_MEDIA){ if (StopFlag.value()) {
  316.          * return; } try { player.stop(); } catch (MediaException ex) { } } }
  317.          */
  318. }