/* * @(#)JMStudio.java 1.29 99/05/19 * * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * */ // The java media packages import javax.media.*; import javax.media.format.*; import javax.media.bean.playerbean.*; import javax.media.format.video.VideoFormat; // Java platform packages import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; import java.util.*; import rtp.*; /** * Application to play media files. Includes a file dialog to open * a file interactively. Can also be given a command line parameter for * a startup media file. * Usage: * java JMStudio file:/ * or * java JMStudio http: * * Eg. java JMStudio file:/C:/MOVIES/PLAYME.MPG * java JMStudio http://www.media.com/playme.mov */ public class JMStudio extends Frame implements ControllerListener, ActionListener { /************************************************************************* * VARIABLES *************************************************************************/ MediaPlayer player = null; MediaPlayer newPlayer = null; static double defaultScale = 1.0; Component controlComp = null; // Controlpanel component Component visualComp = null; // Visual Component Component progressBar = null; // Cache indicator Control jmdControl = null; Panel framePanel; // Panel to hold the above components FileDialog fd = null; Insets insets; Menu menu; Menu visited; PopupMenu zoomMenu = null; OpenURLDialog urlDialog = null; CheckboxMenuItem cbAutoPlay = null; CheckboxMenuItem cbAutoLoop = null; CheckboxMenuItem cbAspectRatio = null; MenuItem itemSaveAs; MenuItem itemClose; MenuItem itemPlugInViewer; MenuItem itemFullScreen; boolean windowCreated = false; static boolean queryCaptureCards = false; boolean newVideo = false; boolean panelResized = false; static int listenPort = 4000; String mediaURL = ""; String filename = ""; String fileDirectory = "."; static Vector fileList = null; static String visitedFile = null; boolean inFullScreen = false; Window screen = null; MouseListener unFullML = null; int fileListSize = 0; ActionListener vfl; static int windowCount = 0; // No. of windows currently open static final String APPNAME = "JMStudio"; static final String LABEL_OPENFILE = "Open File..."; static final String LABEL_OPENURL = "Open URL..."; static final String LABEL_OPENRTPSESSION = "Open RTP Session..."; static final String LABEL_SAVEAS = "Save As..."; static final String LABEL_EXPORT = "Export..."; static final String LABEL_CLOSE = "Close"; static final String LABEL_PLUGINS = "PlugIn Viewer"; static final String LABEL_EXIT = "Exit"; static final String LABEL_FILE = "File"; static final String LABEL_CLONE = "New Window"; static final String LABEL_VISITED = "Visited URLs"; static final String LABEL_OPTIONS = "Player"; static final String LABEL_AUTOLOOP = "Auto Loop"; static final String LABEL_KEEPASPECT = "Maintain Aspect Ratio"; static final String LABEL_AUTOPLAY = "Auto Play"; static final String LABEL_FULLSCREEN = "Full Screen"; static final String LABEL_CAPTUREPREVIEW = "Capture Preview..."; static final String LABEL_HELP = "Help"; static final String LABEL_HELPABOUT = "About JM Studio..."; /************************************************************************* * METHODS *************************************************************************/ /* * Create the GUI and initialize the player */ public JMStudio(MediaPlayer player, String name) { super(APPNAME); this.player = player; if (name != null) { filename = name; mediaURL = name; } if (windowCount == 0) initProps(); windowCount++; setMenuBar(createMenuBar()); if (fileList == null) loadVisitedList(); if (queryCaptureCards) doQueryCaptureCards(); vfl = new ActionListener() { public void actionPerformed(ActionEvent ae) { openURL(ae.getActionCommand()); } }; updateVisitedList(); setLayout( new BorderLayout() ); framePanel = new Panel(); framePanel.setLayout( null ); add(framePanel, "Center"); setBlankSize(); setVisible(true); // Setup AWT listeners addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent we) { killThePlayer(); while (JMStudio.this.player != null) { try { Thread.currentThread().sleep(100); } catch (InterruptedException ie) { } } synchronized (JMStudio.this) { dispose(); } windowCount--; if (windowCount == 0) { saveVisitedList(); System.exit(0); } } }); framePanel.addComponentListener( new ComponentAdapter() { public void componentResized(ComponentEvent ce) { panelResized = true; doResize(); fitFrame(); } }); addComponentListener( new ComponentAdapter() { public void componentResized(ComponentEvent ce) { insets = getInsets(); Dimension dim = getSize(); framePanel.setSize(dim.width - insets.left - insets.right, dim.height - insets.top - insets.bottom); } }); } protected void initProps() { Properties props = new Properties(System.getProperties()); props = new Properties(props); File theUserPropertiesFile; String sep = File.separator; theUserPropertiesFile = new File(System.getProperty("user.home") + sep + ".hotjava" + sep + "properties"); try { FileInputStream in = new FileInputStream(theUserPropertiesFile); props.load(new BufferedInputStream(in)); in.close(); } catch (Exception e) { } System.setProperties(props); } public void addNotify() { super.addNotify(); insets = getInsets(); windowCreated = true; setCenterLocation(this, null, insets.left + insets.right + 320, insets.top + insets.bottom); // Realize the player if (player != null) { player.addControllerListener( this ); player.realize(); } } /* * Resize the window frame when there's no media playing in it. */ private void setBlankSize() { Insets insets = getInsets(); setSize(320 + insets.left + insets.right, insets.top + insets.bottom); checkMenu(); } /* * Sets the size of the frame and centers the frame within the parent frame */ private void setCenterLocation(Frame self, Frame parent, int width, int height) { Rectangle rect; if (parent != null) rect = parent.getBounds(); else { Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); rect = new Rectangle(new Point(0,0), d); } self.setSize(width, height); self.setLocation((rect.x + ((rect.width - width)/2)), (rect.y + ((rect.height - height)/2))); } /* * Zoom the video to full screen and put it in a top-level window */ private void fullScreen(boolean toFullScreen) { if (toFullScreen) { if (visualComp == null) return; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Point location = new Point(0, 0); if (screen == null) { screen = new Window( this ); screen.setSize(screenSize); screen.setLocation(0, 0); screen.setLayout( null ); screen.setBackground(Color.black); screen.addNotify(); } { screen.toFront(); framePanel.remove((MediaPlayer)player); Dimension size = visualComp.getPreferredSize(); if ( (float)size.width/size.height >= (float)screenSize.width/screenSize.height ) { size.height = (size.height * screenSize.width) / size.width; size.width = screenSize.width; location.x = 0; location.y = (screenSize.height - size.height) / 2; } else { size.width = (size.width * screenSize.height) / size.height; size.height = screenSize.height; location.y = 0; location.x = (screenSize.width - size.width) / 2; } screen.add((MediaPlayer) player); ((MediaPlayer)player).setSize(size); ((MediaPlayer)player).setLocation(location); visualComp.addMouseListener( unFullML = new MouseAdapter() { public void mouseClicked(MouseEvent me) { fullScreen(false); } } ); } screen.setVisible(true); } else { visualComp.removeMouseListener(unFullML); screen.setVisible(false); screen.remove((MediaPlayer) player); framePanel.add("Center", (MediaPlayer) player); //visualComp.invalidate(); doResize(); } } private void checkMenu() { boolean enable = (player != null); itemSaveAs.setEnabled(enable); itemClose.setEnabled(enable); itemPlugInViewer.setEnabled(enable); itemFullScreen.setEnabled(enable); } /* * Sleeps for specified number of milliseconds. */ private void sleep(long time) { try { Thread.currentThread().sleep(time); } catch (Exception e) { } } /* * Returns the current media URL. */ String getURL() { return mediaURL; } /* * Creates the menu bar. */ private MenuBar createMenuBar() { MenuItem item; MenuBar mb = new MenuBar(); MenuShortcut shortcut; ActionListener al = this; // File Menu Menu mnFile = new Menu(LABEL_FILE); shortcut = new MenuShortcut(KeyEvent.VK_O); mnFile.add(item = new MenuItem(LABEL_OPENFILE, shortcut)); item.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_U); mnFile.add(item = new MenuItem(LABEL_OPENURL, shortcut)); item.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_R); mnFile.add(item = new MenuItem(LABEL_OPENRTPSESSION, shortcut)); item.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_P); mnFile.add(item = new MenuItem(LABEL_CAPTUREPREVIEW, shortcut)); item.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_A); mnFile.add(itemSaveAs = new MenuItem(LABEL_SAVEAS, shortcut)); itemSaveAs.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_E); mnFile.add(item = new MenuItem(LABEL_EXPORT, shortcut)); item.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_W); mnFile.add(itemClose = new MenuItem(LABEL_CLOSE, shortcut)); itemClose.addActionListener( this ); visited = new Menu(LABEL_VISITED); mnFile.add(visited); shortcut = new MenuShortcut(KeyEvent.VK_N); mnFile.add(item = new MenuItem(LABEL_CLONE, shortcut)); item.addActionListener( this ); mnFile.insertSeparator(7); mnFile.insertSeparator(9); shortcut = new MenuShortcut(KeyEvent.VK_V); mnFile.add(itemPlugInViewer = new MenuItem(LABEL_PLUGINS, shortcut)); itemPlugInViewer.addActionListener( this ); shortcut = new MenuShortcut(KeyEvent.VK_X); mnFile.add(item = new MenuItem(LABEL_EXIT, shortcut)); item.addActionListener( this ); mnFile.insertSeparator(12); // Options Menu Menu mnOptions = new Menu(LABEL_OPTIONS); cbAutoPlay = new CheckboxMenuItem(LABEL_AUTOPLAY); cbAutoPlay.setState(true); mnOptions.add(cbAutoPlay); cbAutoLoop = new CheckboxMenuItem(LABEL_AUTOLOOP); cbAutoLoop.setState(true); mnOptions.add(cbAutoLoop); cbAutoLoop.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent ie) { if (player != null) player.setPlaybackLoop(cbAutoLoop.getState()); } }); cbAspectRatio = new CheckboxMenuItem(LABEL_KEEPASPECT); cbAspectRatio.setState(false); mnOptions.add(cbAspectRatio); shortcut = new MenuShortcut(KeyEvent.VK_F); mnOptions.add(itemFullScreen = new MenuItem(LABEL_FULLSCREEN, shortcut)); itemFullScreen.addActionListener( this ); cbAspectRatio.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent ie) { if (player != null) { player.setFixedAspectRatio(cbAspectRatio.getState()); doResize(); fitFrame(); } } }); Menu mnHelp = new Menu(LABEL_HELP); shortcut = new MenuShortcut(KeyEvent.VK_H); mnHelp.add(item = new MenuItem(LABEL_HELPABOUT, shortcut)); item.addActionListener( this ); this.menu = mnFile; mb.add(mnFile); mb.add(mnOptions); mb.add(mnHelp); return mb; } /** * Resize the visual and control components in the frame panel */ public void doResize() { Dimension d = framePanel.getSize(); int videoHeight = d.height; if (controlComp != null) { videoHeight -= controlComp.getPreferredSize().height; if (visualComp != null) if (videoHeight < 2) videoHeight = 2; if (d.width < 80) d.width = 80; controlComp.setBounds(0, videoHeight, d.width, controlComp.getPreferredSize().height); controlComp.invalidate(); } if (visualComp != null) { ((MediaPlayer)player).setBounds(0, 0, d.width, videoHeight); } framePanel.validate(); } /** * Bring up the open URL dialog */ public void openURL() { if (urlDialog == null) { urlDialog = new OpenURLDialog(this); } urlDialog.show(); } private boolean closeCapture() { if (player == null) return true; // Sun's implementation specific capture devices if ( mediaURL.startsWith("vfw:") || mediaURL.startsWith("javasound:") || mediaURL.startsWith("sunvideo:") || mediaURL.startsWith("sunvideoplus:") || mediaURL.startsWith("ds:") ) { String result = MessageDialog.createOKCancelDialog(this, "Cannot open a capture device " + "twice. Should I close the preview?"); if (result != null && result.equals(MessageDialog.ACTION_OK)) { killThePlayer(); player = null; return true; } else return false; } else // (probably) not a capture device return true; } /** * Close the player */ public synchronized void killThePlayer() { if (player != null) { if (jmdControl != null && jmdControl instanceof Component) { Component c = (Component)jmdControl; c.setVisible(false); jmdControl = null; } player.close(); progressBar = null; setTitle(APPNAME); filename = null; mediaURL = null; } } /** * Handle Controller/Player events for the player that's currently active. */ public synchronized void controllerUpdate(ControllerEvent ce) { // RealizeCompleteEvent occurs after a realize() call. if (ce instanceof RealizeCompleteEvent) { int width = 320; int height = 0; insets = getInsets(); if (progressBar != null) framePanel.remove(progressBar); if (player != null) { if ((visualComp = player.getVisualComponent()) != null) { width = ((MediaPlayer)player).getPreferredSize().width; height = ((MediaPlayer)player).getPreferredSize().height; width = (int) (width * defaultScale); height = (int) (height * defaultScale); framePanel.add((MediaPlayer)player); ((MediaPlayer)player).setBounds(0, 0, width, height); addPopupMenu(visualComp); newVideo = true; } } if ((controlComp = player.getControlPanelComponent()) != null) { int prefHeight = controlComp.getPreferredSize().height; framePanel.add(controlComp); controlComp.setBounds(0, height, width, prefHeight); height += prefHeight; newVideo = true; } jmdControl = player.getControl("com.sun.media.JMD"); // Set the title of the frame to the name of the media file. if (filename != null) { if (filename.indexOf("file:") == 0) { filename = filename.substring(5); } setTitle(filename + " - " + APPNAME); } // Ask the player to prefetch data and prepare to start. player.prefetch(); checkMenu(); } // PrefetchCompleteEvent is generated when the player has finished prefetching // enough data to fill its internal buffers and is ready to start playing. else if (ce instanceof PrefetchCompleteEvent) { if (newVideo) { if (visualComp != null) { Dimension vSize = ((MediaPlayer)player).getPreferredSize(); vSize.width = (int) (vSize.width * defaultScale); vSize.height = (int) (vSize.height * defaultScale); if (controlComp != null) vSize.height += controlComp.getPreferredSize().height; panelResized = false; setSize(vSize.width + insets.left + insets.right, vSize.height + insets.top + insets.bottom); int waited = 0; while (panelResized == false && waited < 2000) { try { waited += 50; Thread.currentThread().sleep(50); Thread.currentThread().yield(); } catch (InterruptedException ie) {} } } else { int height = 1; if (controlComp != null) height = controlComp.getPreferredSize().height; setSize(320+insets.left + insets.right, height + insets.top + insets.bottom); } newVideo = false; } if (cbAutoPlay.getState()) { if (player.getTargetState() != Controller.Started) player.start(); } } // If at any point the Player encountered an error - possibly in the data stream // and it could not recover from the error, it generates a ControllerErrorEvent else if (ce instanceof ControllerErrorEvent) { killThePlayer(); if (visualComp != null) visualComp.remove(zoomMenu); framePanel.removeAll(); visualComp = null; controlComp = null; player.removeControllerListener( this ); player.close(); player = null; setBlankSize(); progressBar = null; } // Occurs when a player is closed. else if (ce instanceof ControllerClosedEvent) { if (visualComp != null) { visualComp.remove(zoomMenu); visualComp = null; } if (controlComp != null) { controlComp = null; } player = null; framePanel.removeAll(); System.gc(); System.runFinalization(); setBlankSize(); progressBar = null; if (newPlayer != null) { player = newPlayer; newPlayer = null; player.addControllerListener(this); player.realize(); validate(); } } // DurationUpdateEvent occurs when the player's duration changes or is // updated for the first time else if (ce instanceof DurationUpdateEvent) { Time t = ((DurationUpdateEvent)ce).getDuration(); } // Caching control. else if (ce instanceof CachingControlEvent) { CachingControl cc = ((CachingControlEvent)ce).getCachingControl(); if (cc != null && progressBar == null) { progressBar = cc.getControlComponent(); if (progressBar == null) progressBar = cc.getProgressBarComponent(); if (progressBar != null) { framePanel.add(progressBar); Dimension prefSize = progressBar.getPreferredSize(); progressBar.setBounds(0, 0, prefSize.width, prefSize.height); insets = getInsets(); framePanel.setSize(prefSize.width, prefSize.height); setSize(insets.left + insets.right + prefSize.width, insets.top + insets.bottom + prefSize.height); } } } else if (ce instanceof StartEvent) { } else if (ce instanceof MediaTimeSetEvent) { } else if (ce instanceof TransitionEvent) { } else if (ce instanceof RateChangeEvent) { } else if (ce instanceof StopTimeChangeEvent) { } else if (ce instanceof SizeChangeEvent) { // The video size has changed, resize the panel if (framePanel != null) { SizeChangeEvent sce = (SizeChangeEvent) ce; int nooWidth = (int) (sce.getWidth() * defaultScale); int nooHeight = (int) (sce.getHeight() * defaultScale); // Add the height of the default control component if (controlComp != null) nooHeight += controlComp.getPreferredSize().height; if ( framePanel.getSize().width != nooWidth || framePanel.getSize().height != nooHeight) { setSize(nooWidth + insets.left + insets.right, nooHeight + insets.top + insets.bottom); } else doResize(); } } if (ce instanceof FormatChangeEvent){ Dimension vSize = new Dimension(320,0); Component oldVisualComp = visualComp; if ((visualComp = player.getVisualComponent()) != null) { if (oldVisualComp != visualComp) { if (oldVisualComp != null) oldVisualComp.remove(zoomMenu); framePanel.remove((MediaPlayer)player); vSize = ((MediaPlayer)player).getPreferredSize(); vSize.width = (int) (vSize.width * defaultScale); vSize.height = (int) (vSize.height * defaultScale); framePanel.add((MediaPlayer)player); ((MediaPlayer)player).setBounds(0, 0, vSize.width, vSize.height); addPopupMenu(visualComp); } } Component oldComp = controlComp; if ((controlComp = player.getControlPanelComponent()) != null) { if (oldComp != controlComp){ framePanel.remove(oldComp); framePanel.add(controlComp); if (controlComp != null){ int prefHeight = controlComp.getPreferredSize().height; controlComp.setBounds(0, vSize.height,vSize.width, prefHeight); } } } }// FormatChangeEvent } public void zoomTo(float z) { insets = getInsets(); if (visualComp != null) { Dimension d = ((MediaPlayer)player).getPreferredSize(); d.width = (int) (d.width * z); d.height = (int) (d.height * z); if (controlComp != null) d.height += controlComp.getPreferredSize().height; setSize(d.width + insets.left + insets.right, d.height + insets.top + insets.bottom); } } private void addPopupMenu(Component visual) { MenuItem mi; zoomMenu = new PopupMenu("Zoom"); if (visual != null) visual.add(zoomMenu); mi = new MenuItem("Scale 1:2"); zoomMenu.add(mi); mi.addActionListener( this ); mi = new MenuItem("Scale 1:1"); zoomMenu.add(mi); mi.addActionListener( this ); mi = new MenuItem("Scale 2:1"); zoomMenu.add(mi); mi.addActionListener( this ); mi = new MenuItem("Scale 4:1"); zoomMenu.add(mi); mi.addActionListener( this ); if (visual != null) visual.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent me) { if (me.isPopupTrigger()) zoomMenu.show(visualComp, me.getX(), me.getY()); } public void mouseReleased(MouseEvent me) { if (me.isPopupTrigger()) zoomMenu.show(visualComp, me.getX(), me.getY()); } public void mouseClicked(MouseEvent me) { if (me.isPopupTrigger()) zoomMenu.show(visualComp, me.getX(), me.getY()); } } ); } public boolean openFile(String filename) { return openURL(filename); } public boolean openURL(String urlName) { MediaLocator mrl = null; MediaPlayer player = null; if ((mrl = new MediaLocator(urlName)) == null) { message("Can't build URL for " + urlName); return false; } // Create an instance of a MediaPlayer bean for this media player = createMediaPlayer(urlName); if (player != null) { player.setPlaybackLoop(cbAutoLoop.getState()); player.setFixedAspectRatio(cbAspectRatio.getState()); player.setPopupActive(false); player.setControlPanelVisible(false); if (this.player == null) { this.player = player; player.addControllerListener(this); player.realize(); this.filename = urlName; } else { newPlayer = player; this.filename = urlName; killThePlayer(); } String url = mrl.toExternalForm(); if (url != null) { mediaURL = urlName; addToFileList(url); updateVisitedList(); } } return (player != null); } /**************************************************************** * Visited URLs Stuff ****************************************************************/ private int getVisitedIndex(String ext) { int index = -1; for (int i = 0; i < visited.getItemCount(); i++) { String item = ((MenuItem)visited.getItem(i)).getLabel(); if (item.equals(ext)) return i; } visited.add(new Menu(ext)); return visited.getItemCount() - 1; } void addToFileList(String url) { if (fileList == null) loadVisitedList(); for (int i = 0; i < fileList.size(); i++) { if (((String)fileList.elementAt(i)).equalsIgnoreCase(url)) return; } fileList.addElement(url); saveVisitedList(); } void loadVisitedList() { fileList = new Vector(); String vf = System.getProperty("user.home"); if (vf != null) { visitedFile = vf + File.separator + "." + APPNAME; File fin = new File(visitedFile); try { if (fin.exists()) { BufferedReader br = new BufferedReader(new FileReader(fin)); String line; while ((line = br.readLine()) != null) { fileList.addElement(line); } br.close(); } else { queryCaptureCards = true; FileOutputStream fout = new FileOutputStream(visitedFile, true); fout.close(); } } catch (IOException ioe) { } } } void saveVisitedList() { if (visitedFile != null && fileList != null && fileList.size() > 0) { try { BufferedWriter bw = new BufferedWriter(new FileWriter(visitedFile)); for (int i = 0; i < fileList.size(); i++) { String url = (String) fileList.elementAt(i); bw.write(url, 0, url.length()); bw.newLine(); } bw.close(); } catch (IOException ioe) { System.err.println("Could not write visited file list"); } } } synchronized void updateVisitedList() { if (fileListSize == fileList.size()) return; for (int i = fileListSize; i < fileList.size(); i++) { String url = (String) fileList.elementAt(i); int extpos = url.lastIndexOf("."); if (extpos < 1) continue; String ext = url.substring(extpos+1).toUpperCase(); int index = getVisitedIndex(ext); Menu filetype = (Menu) visited.getItem(index); MenuItem m = new MenuItem(url); m.addActionListener(vfl); filetype.add(m); } fileListSize = fileList.size(); } /******************************************************************* * MediaPlayer bean *******************************************************************/ MediaPlayer createMediaPlayer(String mediaFile) { MediaPlayer player = null; player = new MediaPlayer(); if (!mediaFile.equals("")) { player.setMediaLocator( new MediaLocator(mediaFile) ); if (player.getPlayer() == null) { message("Could not create player for " + mediaFile); return null; } } return player; } //Make the frame fit the MediaPlayer public void fitFrame() { int controlHeight = 0; if (controlComp != null) controlHeight = controlComp.getPreferredSize().height; if (visualComp != null) { Dimension vcS = visualComp.getSize(); Dimension d = framePanel.getSize(); Insets s = getInsets(); /** if try to be exact, panel would shift between one or two pixel So a fudge factor of 1 pixel either way is put in. **/ if ((d.width < vcS.width-1 || d.width > vcS.width+1) || (d.height < (vcS.height + controlHeight-1) || d.height > (vcS.height + controlHeight+1))) { setSize(vcS.width + s.left + s.right, vcS.height + controlHeight + s.top + s.bottom); } } } /************************************************************************* * Query Capture Devices *************************************************************************/ private void doQueryCaptureCards() { queryCaptureCards = false; Vector captureDevices = CaptureDeviceManager.getDeviceList( new VideoFormat(null) ); if (captureDevices != null && captureDevices.size() > 0) return; // Check if VFWAuto or SunVideoAuto is available Class auto = null; try { auto = Class.forName("VFWAuto"); } catch (Exception e) { } if (auto == null) { try { auto = Class.forName("SunVideoAuto"); } catch (Exception ee) { } } if (auto == null) return; Frame message = new Frame("Querying capture devices..."); message.add(new Label(APPNAME + " is looking for Video Capture devices." + "This might take a few minutes.")); message.pack(); message.setVisible(true); try { Object instance = auto.newInstance(); } catch (ThreadDeath td) { throw td; } catch (Throwable t) { message("Capture device query unsuccesful!"); } message.dispose(); } /************************************************************************* * AWT Event Handling *************************************************************************/ public void actionPerformed(ActionEvent ae) { Object source = ae.getSource(); String command = ae.getActionCommand(); if (command == null && source instanceof MenuItem) command = ((MenuItem)source).getActionCommand(); if (command.equals(LABEL_OPENFILE)) { if (fd == null) { fd = new FileDialog(JMStudio.this, LABEL_OPENFILE, FileDialog.LOAD); } fd.setDirectory(fileDirectory); fd.show(); if (fd.getFile() != null) { fileDirectory = fd.getDirectory(); String filename = fileDirectory + fd.getFile(); openFile("file:" + filename); } } else if (command.equals(LABEL_OPENURL)) { openURL(); } else if (command.equals(LABEL_CAPTUREPREVIEW)) { CaptureDialog cd = new CaptureDialog(JMStudio.this); cd.show(); MediaLocator ml = cd.getLocator(); if (ml != null) { openURL(ml.toExternalForm()); } } else if (command.equals(LABEL_OPENRTPSESSION)){ RTPDialog rtpd = new RTPDialog(JMStudio.this); } else if (command.equals(LABEL_SAVEAS)) { String urlString = JMStudio.this.getURL(); if (urlString != null && urlString.length() > 1 && closeCapture()) { SaveAsDialog sad = new SaveAsDialog(JMStudio.this, urlString); } } else if (command.equals(LABEL_EXPORT)) { String urlString = JMStudio.this.getURL(); if (closeCapture()) { ExportDialog sad = new ExportDialog(JMStudio.this, urlString, JMStudio.this.fileList); } } else if (command.equals(LABEL_CLOSE)) { killThePlayer(); } else if (command.equals(LABEL_PLUGINS)) { if (player != null && jmdControl != null && (jmdControl instanceof Component)) ((Component)jmdControl).setVisible(true); } else if (command.equals(LABEL_FULLSCREEN)) { fullScreen( true ); } else if (command.equals(LABEL_EXIT)) { killThePlayer(); synchronized (JMStudio.this) { dispose(); } windowCount--; if (windowCount == 0) { saveVisitedList(); System.exit(0); } } else if (command.indexOf("1:2") >= 0) { zoomTo(0.5f); } else if (command.indexOf("1:1") >= 0) { zoomTo(1.0f); } else if (command.indexOf("2:1") >= 0) { zoomTo(2.0f); } else if (command.indexOf("4:1") >= 0) { zoomTo(4.0f); } else if (command.equals(LABEL_CLONE)) { JMStudio jpnew = new JMStudio(null, null); jpnew.fileDirectory = fileDirectory; jpnew.cbAutoPlay.setState(cbAutoPlay.getState()); jpnew.cbAutoLoop.setState(cbAutoLoop.getState()); jpnew.cbAspectRatio.setState(cbAspectRatio.getState()); } else if (command.equals(LABEL_HELPABOUT)) { AboutDialog.createDialog (JMStudio.this); } } /************************************************************************* * Entry point for application *************************************************************************/ public static void main(String [] args) { int i = 0; while (i < args.length) { MediaPlayer player = null; String mediaFile = args[i]; if (mediaFile.equals("-x") && i+1 < args.length) { String scale = args[i+1]; try { defaultScale = Double.valueOf(scale).doubleValue(); } catch (NumberFormatException nfe) { defaultScale = 1.0; } i += 2; continue; } MediaLocator mrl = null; if (mediaFile.indexOf(":") < 2) { if (mediaFile.indexOf("/") != 0) mediaFile = "/" + mediaFile; mediaFile = "file:" + mediaFile; } JMStudio jmstudio = new JMStudio(null, null); jmstudio.openURL(mediaFile); i++; } if (JMStudio.windowCount == 0) new JMStudio(null, null); } private void message(String s) { MessageDialog.createErrorDialog(this, s); } /************************************************************************* * INNER CLASSES *************************************************************************/ public class OpenURLDialog extends Dialog { TextField url; OpenURLDialog(Frame frame) { // super(frame, true); super(frame, false); Button button; Panel row; setTitle("Open URL"); setBackground(Color.lightGray); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { cancel(); } }); setLayout(new BorderLayout()); row = new Panel(); row.setLayout(new FlowLayout()); row.add(new Label("URL:", Label.RIGHT)); url = new TextField("", 30); url.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { open(); } }); row.add(url); add("North", row); row = new Panel(); row.setLayout(new FlowLayout()); row.add(button = new Button("Open")); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { open(); } }); row.add(button = new Button("Cancel")); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { cancel(); } }); add("South", row); pack(); setResizable(false); } public void setVisible(boolean show) { super.setVisible(show); url.selectAll(); url.requestFocus(); } public void open() { if (openURL(url.getText())) { setVisible(false); } } public void cancel() { setVisible(false); } } }