/** * A JMF example xlet for XleTView. PLease note that due to the nature of JMF * support in XleTView, this example will NOT work on a normal MHP * implementation without a few changes. * * This is based on an example xlet posted to the XleTView forums by Martin * Sveden. A couple of changes have been made to his original version in * order to fix minor bugs, and comments have been added. * * Thanks to Martin and the rest of the XleTView team for their work in helping * newcomers to the MHP community to get started with an easy way of developing * xlets. It's appreciated, guys, and not just by the newbies! * -- Steve Morris */ import java.awt.Component; import java.awt.Rectangle; import java.io.IOException; import javax.media.*; import javax.media.protocol.*; import javax.tv.xlet.*; import org.havi.ui.*; public class XletviewJMFExample extends HContainer implements Xlet, ControllerListener { // The URL of the video that we will display. For XleTView we must use a // file:// URL because we don't have a broadcast interface. // // This will NOT work in a real MHP or OCAP implementation because MHP and // OCAP do not support playing a video from a file. In a real // implementation, this URL should be a dvb:// or ocap:// URL, depending // on the platform. private static final String VIDEO_URL = "file://d://ch1.avi"; private static final String VIDEO_URL_2 = "file://d://ch2.avi"; // Instance variables private HScene scene; private XletContext context; private Player player; public void initXlet(XletContext ctx) throws XletStateChangeException { // Store our XletXontext because we will need it later. this.context = context; // Get an HScene so that we can display ourselves. // First we get a reference to the HSceneFactory that will create our // HScene. HSceneFactory factory = HSceneFactory.getInstance(); // Build a full-screen HSceneTemplate. HSceneTemplate hst = new HSceneTemplate(); hst.setPreference(HSceneTemplate.SCENE_SCREEN_DIMENSION, new org.havi.ui.HScreenDimension(1, 1), HSceneTemplate.REQUIRED); hst.setPreference(HSceneTemplate.SCENE_SCREEN_LOCATION, new org.havi.ui.HScreenPoint(0, 0), HSceneTemplate.REQUIRED); // Now get our HScene. scene = factory.getBestScene(hst); // If we can't get an HScene that meets our needs, die. if (scene == null) throw new XletStateChangeException("Can't create HScene"); // If we have got a suitable HScene, set our size to be the full size of // the HScene and add ourselves to it. Rectangle rect = scene.getBounds(); setBounds(rect); scene.setVisible(false); scene.add(this); } public void startXlet() { // first, create a MediaLocator for the video we want to play. In a // normal MHP or OCAP implementation this would be created from a // dvb:// or ocap:// URL respectively. javax.media.MediaLocator locator; //Set our scene to be visible. Later in the Xlet we will put the video // in an HComponent, so we need a visible HScene in which to display it. scene.setVisible(true); while (true) { try { // Create a data source for our locator. We could create the player // directly by calling Manager.createPlayer() with the MediaLocator if we // preferred - the effect is the same. locator = new javax.media.MediaLocator(VIDEO_URL); DataSource playingDataSource = Manager.createDataSource(locator); // Now create the player player = Manager.createPlayer(playingDataSource); // Add ourselves as a listener for events from the player player.addControllerListener(this); // Start the player. At this point, any video would be played in the // background on a normal MHP or OCAP receiver. player.start(); System.out.println("sleeping..."); Thread.sleep(10000); System.out.println("stopping video 1") player.stop(); Thread.sleep(5000); System.out.println("deallocating video 1") player.deallocate(); Thread.sleep(5000); System.out.println("closing video 1") player.close(); Thread.sleep(5000); System.out.println("starting video 2") locator = new javax.media.MediaLocator(VIDEO_URL_2); playingDataSource = Manager.createDataSource(locator); player = Manager.createPlayer(playingDataSource); player.addControllerListener(this); player.start(); System.out.println("started video 2") Thread.sleep(10000); } catch (IOException e) { e.printStackTrace(); } catch (MediaException e) { e.printStackTrace(); } } } public void pauseXlet() { // Pausing ur Xlet should free any scarce resources. Since the MPEG decoder // is usually a scarce resource (but not in XleTView), we will stop our // player and destroy it. player.stop(); player.close(); player = null; } public void destroyXlet(boolean unconditional) { // Stop and destroy the player. player.stop(); player.close(); player = null; // Destroy our HScene. We must remember to do this because the middleware // may be storing references to our HScene. If we do not dispose of the // HScene (and any other graphics objects, etc.) then these references will // continue to exist, the object may not get garbage collected and we leak // memory. if (scene != null) { scene.setVisible(false); scene.remove(this); HSceneFactory.getInstance().dispose(scene); } scene = null; } /** * Handle events from the JMF Player. * * In this case we only care about two events and ignore any others. */ public void controllerUpdate(ControllerEvent event) { // Print out the event we have received on the debug console. System.out.println("" + event); // Has the player finished realizing? if (event instanceof RealizeCompleteEvent) { // Try to display the video in a window (admittedly, a full-screen window) Component comp; // Calling getVisualComponent() will convert the player from a // 'background player' (which plays its video in the video plane) // to a 'component player' (which plays its video in an AWT component). // This is a one-way operation, so the only way to go back is to // destroy the current player and create a new one. If the operation // fails, then the player will remain as a background player. if ((comp = player.getVisualComponent()) != null) { add(comp); System.out.println("Added " + comp + " as a video component"); // Set the size and position (full screen, placed in the top left corner) // and draw it. comp.setSize(720, 576); setSize(720, 576); validate(); repaint(); } } else if (event instanceof EndOfMediaEvent) { // We've reached the end of the media; rewind and // start over. // Note that setMediaTime() will NOT work in this way on a real MHP // implementation. The concept of 'media time' has no real meaning in a // broadcast environment, and so xlets can only set the media time of // audio clips that are played from a file. player.setMediaTime(new Time(0)); player.start(); } } }