/* * File : JMFActiveMediaPlayer.java * Created : 02-may-2001 10:56 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2005 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details (see the LICENSE file). */ package edu.xtec.jclic.media; import edu.xtec.jclic.PlayStation; import edu.xtec.jclic.bags.MediaBag; import edu.xtec.jclic.boxes.ActiveBox; import edu.xtec.util.ExtendedByteArrayInputStream; import edu.xtec.util.StreamIO; import java.awt.Component; import java.io.ByteArrayInputStream; import java.io.InputStream; import javax.media.Player; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequencer; /** * * @author Francesc Busquets (fbusquets@xtec.cat) * @version 13.08.28 */ public class JMFActiveMediaPlayer extends ActiveMediaPlayer implements javax.media.ControllerListener { public static Sequencer sequencer=null; javax.media.Player player; javax.media.protocol.DataSource dataSource; boolean midi; ByteArrayInputStream midiIs; /** Creates new JMFActiveMediaPlayer */ public JMFActiveMediaPlayer(edu.xtec.jclic.media.MediaContent mc, MediaBag mb, PlayStation ps) { super(mc, mb, ps); player=null; dataSource=null; midi=false; midiIs=null; if(!useAudioBuffer){ try{ switch(mc.mediaType){ case MediaContent.PLAY_MIDI: midi=true; InputStream is=mb.getInputStream(mc.mediaFileName); if(is instanceof ByteArrayInputStream) midiIs=(ByteArrayInputStream)is; else midiIs=new ExtendedByteArrayInputStream(StreamIO.readInputStream(is), mc.mediaFileName); break; default: Object source=mb.getMediaDataSource(mc.mediaFileName); if(source instanceof ExtendedByteArrayInputStream){ dataSource=new ByteDataSource((ExtendedByteArrayInputStream)source); } else if(source instanceof String){ javax.media.MediaLocator ml=new javax.media.MediaLocator((String)source); dataSource=javax.media.Manager.createDataSource(ml); } } } catch(Exception ex){ System.err.println("Error reading media \""+mc.mediaFileName+"\":\n"+ex); } } } public AudioBuffer createAudioBuffer(int seconds) throws Exception{ return new JavaSoundAudioBuffer(mc.length); } public static void closeMidiSequencer(){ if(sequencer!=null){ if(sequencer.isRunning()) sequencer.stop(); if(sequencer.isOpen()) sequencer.close(); } } public void realize(){ if(!useAudioBuffer){ try{ if(midi){ if(sequencer==null) sequencer=MidiSystem.getSequencer(); } else{ if(player==null && dataSource!=null){ player=javax.media.Manager.createPlayer(dataSource); if(player!=null) player.addControllerListener(this); } if(player!=null && player.getState()<Player.Realized) player.realize(); } } catch(Exception e){ System.err.println("Error realizing media \""+mc.mediaFileName+"\"\n"+e); } } } @Override protected void playNow(ActiveBox setBx){ if(useAudioBuffer) super.playNow(setBx); else{ try{ if(midi){ if(sequencer==null) realize(); if(sequencer!=null && midiIs!=null){ if(sequencer.isRunning()) sequencer.stop(); if(!sequencer.isOpen()) sequencer.open(); midiIs.reset(); sequencer.setSequence(midiIs); sequencer.stop(); setTimeRanges(); sequencer.start(); } } else{ if(player==null && dataSource!=null) realize(); if(player!=null){ boolean retry=false; if(mc.mediaType==MediaContent.PLAY_VIDEO) linkTo(setBx); if(player.getState()>=Player.Realized){ setTimeRanges(); attachVisualComponent(); } else{ retry=true; //System.out.println("starting without realized player - retrying"); } player.start(); if(retry){ if(player.getState()>=Player.Realized){ attachVisualComponent(); } //else //System.out.println("starting without realized player!"); } } } } catch(Exception e){ System.err.println("Error playing media \""+mc.mediaFileName+"\":\n"+e); } } } @Override public void stop() { super.stop(); if(!useAudioBuffer){ try{ if(midi && sequencer!=null){ closeMidiSequencer(); } else if (player!=null && player.getState()==Player.Started) player.stop(); } catch(Exception e){ System.err.println("Error stopping media \""+mc.mediaFileName+"\":\n"+e); } } } @Override public void clear(){ super.clear(); if(!useAudioBuffer){ try{ if(midi){ if(sequencer!=null){ sequencer.close(); sequencer=null; } if(midiIs!=null){ midiIs.close(); midiIs=null; } } else if(player!=null){ destroyVisualComponent(); player.close(); //if(player!=null) player.deallocate(); //player=null; } } catch(Exception e){ System.err.println("Error closing media \""+mc.mediaFileName+"\":\n"+e); } } } public void controllerUpdate(javax.media.ControllerEvent event) { if (player == null) return; try{ if(event instanceof javax.media.RealizeCompleteEvent) { setTimeRanges(); attachVisualComponent(); if(player!=null) player.prefetch(); } //else if (event instanceof CachingControlEvent) { //} else if (event instanceof javax.media.EndOfMediaEvent) { if(mc.loop){ player.setMediaTime(new javax.media.Time(0)); player.start(); } } else if (event instanceof javax.media.ControllerErrorEvent) { ps.setSystemMessage(ps.getMsg("msg_error_playing_media"), ""); System.err.println("Controller error event:\n"+((javax.media.ControllerErrorEvent)event).getMessage()); clear(); } else if (event instanceof javax.media.ControllerClosedEvent) { visualComponent=null; destroyVisualComponent(); player.deallocate(); player=null; } } catch(Exception e){ System.err.println("Controller event update error for \""+mc.mediaFileName+"\":\n"+e); } } protected void setTimeRanges(){ if(useAudioBuffer) return; try{ if(midi && sequencer!=null){ sequencer.setTickPosition(0L); /* if(mc.from!=-1){ //sequencer.setTickPosition(sequencer.getSequence().getResolution()*mc.from/2); } else sequencer.setTickPosition(0L); //if(mc.to!=-1){ // sequencer. //} */ } else if(player!=null && player.getState()>=Player.Realized){ if(mc.from!=-1) player.setMediaTime(new javax.media.Time(1000000L*mc.from)); else player.setMediaTime(new javax.media.Time(0L)); if(mc.to!=-1) player.setStopTime(new javax.media.Time(1000000L*mc.to)); } } catch(Exception e){ System.err.println("Error setting time ranges for \""+mc.mediaFileName+"\":\n"+e); } } protected Component getVisualComponent(){ if(player==null || player.getState()<javax.media.Player.Realized) return null; else return player.getVisualComponent(); } }