Package net.sf.fmj.gst.media.content.unknown

Source Code of net.sf.fmj.gst.media.content.unknown.Handler

package net.sf.fmj.gst.media.content.unknown;

import java.awt.Component;
import java.awt.Dimension;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.media.ClockStoppedException;
import javax.media.IncompatibleSourceException;
import javax.media.MediaLocator;
import javax.media.Time;
import javax.media.protocol.DataSource;

import net.sf.fmj.ejmf.toolkit.media.AbstractPlayer;
import net.sf.fmj.gui.controlpanelfactory.ControlPanelFactorySingleton;
import net.sf.fmj.utility.LoggerSingleton;
import net.sf.fmj.utility.URLUtils;

import org.gstreamer.Bus;
import org.gstreamer.Gst;
import org.gstreamer.GstObject;
import org.gstreamer.MainLoop;
import org.gstreamer.elements.PlayBin;
import org.gstreamer.swing.GstVideoComponent;


/**
*
* Handler for GStreamer, which bypasses most of JMF (parsers, codecs).
* TODO: properly indicate EOM.
* @author Ken Larson
*
*/
public class Handler extends AbstractPlayer
{

  private static final Logger logger = LoggerSingleton.logger;

  private boolean prefetchNeeded = true;
 
  private static final boolean TRACE = true;
 
    private PlayBin playbin;
    private GstVideoComponent videoComponent;
  // TODO: audio component?
 
  private static boolean gstInitialized;
  private static void initGstreamer()
  {
    if (gstInitialized)
      return;
   
    logger.info("Initializing gstreamer");
    
    try
    {
      Gst.init("FMJ GStreamer Handler", new String[] {});
     
         Thread t = new Thread("GST MainLoop Thread")
         {
           @Override
        public void run()
           {
             new MainLoop().run(); // TODO: what do we do with this?
              }
         };
         t.setDaemon(true);
         t.start();
          
   
      gstInitialized = true;
    }
    catch (Throwable t)
    {
      logger.log(Level.WARNING, "Unable to initialize gstreamer: " + t, t);
    }
  }
 
 
    @Override
  public void setSource(DataSource source) throws IncompatibleSourceException
  {
       if (TRACE) logger.fine("DataSource: " + source);

       initGstreamer();
       if (!gstInitialized)
         throw new IncompatibleSourceException("Unable to initialize gstreamer");

    if (source.getLocator() == null)
         throw new IncompatibleSourceException("null source locator");
     
      super.setSource(source);
     
  }
   
 
  @Override
  public void doPlayerClose()
  {
    // TODO
    logger.info("Handler.doPlayerClose");
  }

 
  @Override
  public boolean doPlayerDeallocate()
  {
    logger.info("Handler.doPlayerDeallocate");
//    if (playbin != null)
//      playbin.dispose();  // causes JVM crash
    return true;
  }

 
  @Override
  public boolean doPlayerPrefetch()
  {
    if( ! prefetchNeeded ) return true;
    
    prefetchNeeded = false;
    return true;
  }

 
  @Override
  public boolean doPlayerRealize()
  {

    MediaLocator locator = getSource().getLocator();
   
    // workaround because JMF does not like relative file URLs.
    if (locator.getProtocol().equals("file"))
    {  final String newUrl = URLUtils.createAbsoluteFileUrl(locator.toExternalForm());
      if (newUrl != null)
      {
        final MediaLocator newSource = new MediaLocator(newUrl);
        if (!locator.toExternalForm().equals(newSource.toExternalForm()))
        {
          logger.warning("Changing file URL to absolute, from " + locator.toExternalForm() + " to " + newSource);
          locator = newSource;
        }
      }
    }
   
    final String path = locator.toExternalForm();
   
    // logic copied from GstVideoPlayer
    URI uri = parseURI(path);
        playbin = new PlayBin(uri.toString());
        playbin.setURI(uri);
        videoComponent = new GstVideoComponent();
       
        playbin.getBus().connect(new Bus.EOS() {
            public void eosMessage(GstObject source) {
             
              logger.info("GST eosMessage");
             
                final Thread thread = new Thread("GST EOS Thread") {
                    @Override
              public void run() {

                      playbin.stop()// we have to do this in a thread, or it will hang
                      // if we don't do it at all, and the GUI calls  player.setMediaTime(new Time(0));
                      // we end up playing it again.
                     
                      logger.info("GST eosMessage, posting EOM");
                      try
            {
              endOfMedia();
            } catch (ClockStoppedException e)
            {
              logger.log(Level.WARNING, "" + e, e);
            }
                      logger.info("GST eosMessage, done");
           
                    }
                };

                getThreadQueue().addThread(thread);
            
            }
        });
        playbin.setVideoSink(videoComponent.getElement());
       
        videoComponent.setPreferredSize(new Dimension(640, 480))// TODO: get media size
        return true;
  }
 
  /** Copied from GstVideoPlayer */
    private static URI parseURI(String uri) {
        try {
            URI u = new URI(uri);
            if (u.getScheme() == null) {
                throw new URISyntaxException(uri, "Invalid URI scheme");
            }
            return u;
        } catch (URISyntaxException e) {
            File f = new File(uri);
            if (!f.exists()) {
                throw new IllegalArgumentException("Invalid URI/file " + uri, e);
            }
            return f.toURI();
        }
    }


 
  @Override
  public void doPlayerSetMediaTime(Time t)
  {
    logger.info("Handler.doPlayerSetMediaTime " + t.getNanoseconds());
    // TODO: untested since getPosition is always returning 0, the FMJStudio app does not allow us to seek.
    playbin.setPosition(new org.gstreamer.Time(t.getNanoseconds()));
   
  }

 
  @Override
  public float doPlayerSetRate(float rate)
  {
    logger.fine("Handler.doPlayerSetRate " + rate);
    return rate;  // TODO
  }

 
  @Override
  public boolean doPlayerStop()
  {
    logger.fine("Handler.doPlayerStop ");
        playbin.stop();
    return true;
  }

 
  @Override
  public boolean doPlayerSyncStart(Time t)
  {
   
    logger.info("Handler.doPlayerSyncStart" + t);
   
        if (!playbin.isPlaying())
        {
            playbin.play();
        }


    return true;
  }

 
  @Override
  public Time getPlayerDuration()
  {
        if (getState() < Realized)
    {
      return DURATION_UNKNOWN;
    }
         else
         {
           final long durationNanos = playbin.getDuration().longValue();
           if (durationNanos <= 0// TODO: why are we getting 0?
             return DURATION_UNKNOWN; 
           return new Time(durationNanos);
         }
  }

 
  @Override
  public synchronized Time getMediaTime()
  {
       if (getState() < Realized)
    {
      return super.getMediaTime();
    }
         else
         {
           return new Time(playbin.getPosition().longValue());
         }
  }



 
  @Override
  public Time getPlayerStartLatency()
  {
    return new Time(0);
  }

 
  @Override
  public Component getVisualComponent()
  {
    return videoComponent;
  }



//  @Override
//  public Component getControlPanelComponent()
//  {
//    if (qtcMovieController == null)
//      return null;
//    return qtcMovieController.asComponent();
//  }
 
  // until we figure out how to isolate GST's control panel component (get it without the movie panel),
  // we'll use FMJ's control panel.  See GstVideoPlayer
    @Override
  public Component getControlPanelComponent() {
        Component c = super.getControlPanelComponent();

        if( c == null ) {
            c = ControlPanelFactorySingleton.getInstance().getControlPanelComponent(this);
            setControlPanelComponent(c);
        }

        return c;
    }

}
TOP

Related Classes of net.sf.fmj.gst.media.content.unknown.Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.