thanaras 0 Newbie Poster

Hello. I have those 2 classes and what i want to do is capture video in Grayscale, and then manage to take individual frames so as to procces them. The classes are modified classes, from a book called Java Media Apis (2002). I would be thankfull if you could take a quick look.

import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import java.util.*;

/*******************************************************************
* A simple application to allow users to capture audio or video
* through devices connected to the PC. Via command-line arguments
* the user specifies whether audio (-a) or video (-v) capture,
* the duration of the capture (-d) in seconds, and the file to
* write the media to (-f).
*
* The application would be far more useful and versatile if it
* provided control over the formats of the audio and video
* captured as well as the content type of the output.
*
* The class searches for capture devices that support the
* particular default track formats: linear for audio and
* Cinepak for video. As a fall-back two device names are
* hard-coded into the application as an example of how to
* obtain DeviceInfo when a device's name is known. The user may
* force the application to use these names by using the -k
* (known devices) flag.
*
* The class is static but employs the earlier Location2Location
* example to perform all the Processor and DataSink related work.
* Thus the application chiefly involves CaptureDevice related
* operations.
*
* @author Michael (Spike) Barlow
********************************************************************/
public class SimpleRecorder {

/////////////////////////////////////////////////////////////
// Names for the video capture devices on the
// author's system. These will vary system to system but are
// only used as a fallback.
/////////////////////////////////////////////////////////////
private static final String VIDEO_DEVICE_NAME = "vfw:Microsoft WDM Image Capture (Win32):0";

///////////////////////////////////////////////////////////
// Default names for the files to write the output to for
// the case where they are not supplie by the user.
//////////////////////////////////////////////////////////
private static final String DEFAULT_VIDEO_NAME = "file://./captured.avi";

///////////////////////////////////////////
// Type of capture requested by the user.
//////////////////////////////////////////
private static final String VIDEO = "video";

////////////////////////////////////////////////////////////////////
// The only video formats that the particular application
// supports. A better program would allow user selection of formats
// but would grow past the small example size.
////////////////////////////////////////////////////////////////////
private static final Format VIDEO_FORMAT = new VideoFormat(VideoFormat.CINEPAK);


public static void main(String[] args) 
{
  //////////////////////////////////////////////////////
  // Object to handle the processing and sinking of the
  // data captured from the device.
  //////////////////////////////////////////////////////
  Location2Location capture;

  /////////////////////////////////////
  // video capture devices.
  ////////////////////////////////////
  CaptureDeviceInfo videoDevice = null;

  /////////////////////////////////////////////////////////////
  // Capture device's "location" plus the name and location of
  // the destination.
  /////////////////////////////////////////////////////////////
  MediaLocator      captureLocation = null;
  MediaLocator      destinationLocation;
  String            destinationName = null;

  ////////////////////////////////////////////////////////////
  // Formats the Processor (in Location2Location) must match.
  ////////////////////////////////////////////////////////////
  Format[]          formats = new Format[1];

  ///////////////////////////////////////////////
  // Content type for video capture.
  //////////////////////////////////////////////
  ContentDescriptor videoContainer = new
                 ContentDescriptor(FileTypeDescriptor.MSVIDEO);
  ContentDescriptor container = null;

  ///////////////////////////////////////////////////////////////////
  // Duration of recording (in seconds) and period to wait afterwards
  ///////////////////////////////////////////////////////////////////
  double            duration = 10;
  int               waitFor = 0;

  //////////////////////////
  // Video capture?
  //////////////////////////
  String            selected = VIDEO;

  ////////////////////////////////////////////////////////
  // All devices that support the format in question.
  // A means of "ensuring" the program works on different
  // machines with different capture devices.
  ////////////////////////////////////////////////////////
  Vector            devices;

  //////////////////////////////////////////////////////////
  // Whether to search for capture devices that support the
  // format or use the devices whos names are already
  // known to the application.
  //////////////////////////////////////////////////////////
  boolean           useKnownDevices = false;


  /////////////////////////////////////////////////////////////////
  // Perform setup for video capture. Includes finding a suitable
  // device, obatining its MediaLocator and setting the content
  // type.
  ////////////////////////////////////////////////////////////////
  if (selected.equals(VIDEO)) {
    devices = CaptureDeviceManager.getDeviceList(VIDEO_FORMAT);
    if (devices.size()>0 && !useKnownDevices)
      videoDevice = (CaptureDeviceInfo)devices.elementAt(0);
    else
      videoDevice =
          CaptureDeviceManager.getDevice(VIDEO_DEVICE_NAME);
    if (videoDevice==null) {
      System.out.println("Can't find suitable video "
         + "device. Exiting");
      System.exit(1);
    }
    captureLocation = videoDevice.getLocator();
    formats[0] = VIDEO_FORMAT;
    if (destinationName==null)
      destinationName = DEFAULT_VIDEO_NAME;
    container = videoContainer;
  }

  ///////////////////////////////////////////////////////////////////
  // Perform all the necessary Processor and DataSink preparation via
  // the Location2Location class.
  ///////////////////////////////////////////////////////////////////
  destinationLocation = new MediaLocator(destinationName);
  System.out.println("Configuring for capture. Please wait.");
  capture = new Location2Location(captureLocation,
                      destinationLocation,formats,container,1.0);

  ///////////////////////////////////////////////////////////////////
  // Start the recording and tell the user. Specify the length of the
  // recording. Then wait around for up to 4-times the duration of
  // recording (can take longer to sink/write the data so should wait
  // a bit incase).
  ///////////////////////////////////////////////////////////////////
  System.out.println("Started recording " + duration +
          " seconds of " + selected + " ...");
  capture.setStopTime(new Time(duration));
  if (waitFor==0)
    waitFor = (int)(4000*duration);
  else
    waitFor *= 1000;
  int waited = capture.transfer(waitFor);

  /////////////////////////////////////////////////////////
  // Report on the success (or otherwise) of the recording.
  /////////////////////////////////////////////////////////
  int state = capture.getState();
  if (state==Location2Location.FINISHED)
    System.out.println(selected + " capture successful " +
      "in approximately " + ((int)((waited+500)/1000)) +
      " seconds. Data written to " + destinationName);
  else if (state==Location2Location.FAILED)
    System.out.println(selected + " capture failed " +
      "after approximately " + ((int)((waited+500)/1000)) +
      " seconds");
  else {
    System.out.println(selected + " capture still ongoing " +
      "after approximately " + ((int)((waited+500)/1000)) +
      " seconds");
    System.out.println("Process likely to have failed");
  }

  System.exit(0);
}
}




import javax.media.*;
import javax.media.datasink.*;
import javax.media.protocol.*;

/***************************************************************
* Transfer media from one location to another carrying out the
* specified transcoding (track formats and content type) at the
* same time.
*<p>Users specify a source and destination location, the
* Formats (to be realised) of the individual tracks, and a
* ContentDescriptor (content type) for output.
*<p>A Processor is created to perform and transcoding and its
* output DataSource is employed to construct a DataSink in
* order to complete the transfer.
*<p>The most important method of the class is transfer() as
* this opens and starts the DataSink. The constructor builds
* both the Processor (which is starts) and the DataSink.
*<p>The object keeps track of its own state, which can be queried
* with the getState() method. Defined constants are FAILED,
* TRANSLATING, TRANSFERRING, and FINISHED. The process is
* asychronous: transcoding largish movies can take a long time.
* The calling code should make allowances for that.
****************************************************************/
public class Location2Location implements ControllerListener {

  /** Output of the Processor: the transcoded media. */
  protected DataSource  source;

  /** Sink used to "write" out the transcoded media. */
  protected DataSink  sink;

  /** Processor used to transcode the media. */
  protected Processor processor;

  /** Model used in constructing the processor, and which
  * specifies track formats and output content type */
  protected ProcessorModel  model;

  /** State the object is in. */
  protected int   state;

  /** Location that the media will be "written" to. */
  protected MediaLocator  sinkLocation;

  /** The rate of translation. */
  protected float translationRate;

  /** Process has failed. */
  public static final int FAILED = 0;

  /** Processor is working but not finished. DataSink is yet
  * to start. */
  public static final int TRANSLATING = 1;

  /** DataSink has started but not finished. */
  public static final int TRANSFERRING = 3;

  /** Transcoding and transfer is complete. */
  public static final int FINISHED = 4;

  /** String names for each of the states. More user friendly */
  private static final String[] STATE_NAMES = {
    "Failed", "Translating", "<UNUSED>", "Transferring",
    "Finished"};

  /** Period (in milliseconds) between checks for the blocking
  * transfer method. */
  public static final int WAIT_PERIOD = 50;

  /** Wait an "indefinite" period of time for the transfer
  * method to complete. i.e., pass to transfer() if the
  * user wishes to block till the process is complete,
  * regardless of how long it will take. */
  public static final int INDEFINITE = Integer.MAX_VALUE;

/*******************************************************************
* Construct a transfer/transcode object that transfers media from
* sourceLocation to destinationLocation, transcoding the tracks as
* specified by the outputFormats. The output media is to have a
* content type of outputContainer and the process should (if
* possible) run at the passed rate.
*********************************************************************/
Location2Location(MediaLocator sourceLocation,
    MediaLocator destinationLocation, Format[] outputFormats,
    ContentDescriptor outputContainer, double rate) {

  //////////////////////////////////////////////
  // Construct the processor for the transcoding
  //////////////////////////////////////////////
  state = TRANSLATING;
  sinkLocation = destinationLocation;
  try {
    if (sourceLocation==null)
      model = new ProcessorModel(outputFormats,outputContainer);
    else
      model = new ProcessorModel(sourceLocation,
                   outputFormats,outputContainer);
    processor = Manager.createRealizedProcessor(model);
  }
  catch (Exception e) {
    state = FAILED;
    return;
  }

  translationRate = processor.setRate((float)Math.abs(rate));
  processor.addControllerListener(this);

  ////////////////////////////////////////////////////////////
  // Construct the DataSink and employ an anonymous class as
  // a DataSink listener in order that the end of transfer
  // (completion of task) can be detected.
  ///////////////////////////////////////////////////////////
  source = processor.getDataOutput();
  try {
    sink = Manager.createDataSink(source,sinkLocation);
  }
  catch (Exception sinkException) {
    state = FAILED;
    processor.removeControllerListener(this);
    processor.close();
    processor = null;
    return;
  }
  sink.addDataSinkListener(new DataSinkListener() {
      public void dataSinkUpdate(DataSinkEvent e) {
        if (e instanceof EndOfStreamEvent) {
          sink.close();
          source.disconnect();
          if (state!=FAILED)
            state = FINISHED;
        }
        else if (e instanceof DataSinkErrorEvent) {
          if (sink!=null)
            sink.close();
          if (source!=null)
            source.disconnect();
          state = FAILED;
        }
      }
  });
  // Start the transcoding
  processor.start();
}


/***************************************************************
* Alternate constructor: source and destination specified as
* Strings, and no rate provided (hence rate of 1.0)
****************************************************************/
Location2Location(String sourceName, String destinationName,
    Format[] outputFormats, ContentDescriptor outputContainer) {

  this(new MediaLocator(sourceName), new MediaLocator(destinationName),
    outputFormats, outputContainer);
}


/****************************************************************
* Alternate constructor: No rate specified therefore rate of 1.0
*****************************************************************/
Location2Location(MediaLocator sourceLocation,
    MediaLocator destinationLocation, Format[] outputFormats,
    ContentDescriptor outputContainer) {

  this(sourceLocation,destinationLocation,outputFormats,outputContainer,1.0f);
}


/***************************************************************
* Alternate constructor: source and destination specified as
* Strings.
****************************************************************/
Location2Location(String sourceName, String destinationName,
    Format[] outputFormats, ContentDescriptor outputContainer,
    double rate) {

  this(new MediaLocator(sourceName), new MediaLocator(destinationName),
    outputFormats, outputContainer, rate);
}


/**************************************************************
* Respond to events from the Processor performing the transcoding.
* If its task is completed (end of media) close it down. If there
* is an error close it down and mark the process as FAILED.
*****************************************************************/
public synchronized void controllerUpdate(ControllerEvent e) {

  if (state==FAILED)
    return;

  // Transcoding complete.
  if (e instanceof StopEvent) {
    processor.removeControllerListener(this);
    processor.close();
    if (state==TRANSLATING)
      state = TRANSFERRING;
  }
  // Transcoding failed.
  else if (e instanceof ControllerErrorEvent) {
    processor.removeControllerListener(this);
    processor.close();
    state = FAILED;
  }
}



/***********************************************************
* Initiate the transfer through a DataSink to the destination
* and wait (block) until the process is complete (or failed)
* or the supplied number of milliseconds timeout has passed.
* The method returns the total amount of time it blocked.
*************************************************************/
public int transfer(int timeOut) {

  // Can't initiate: Processor already failed to transcode
  ////////////////////////////////////////////////////////
  if (state==FAILED)
    return -1;

  // Start the DataSink
  //////////////////////
  try {
    sink.open();
    sink.start();
   }
  catch (Exception e) {
    state = FAILED;
    return -1;
  }
  if (state==TRANSLATING)
    state = TRANSFERRING;
  if (timeOut<=0)
    return timeOut;

  // Wait till the process is complete, failed, or the
  // prescribed time has passed.
  /////////////////////////////////////////////////////
  int waited = 0;
  while (state!=FAILED && state!=FINISHED && waited<timeOut) {
    try { Thread.sleep(WAIT_PERIOD); }
    catch (InterruptedException ie) { }
    waited += WAIT_PERIOD;
  }
  return waited;
}


/***************************************************
* Initiate the transfer through a DataSink to the
* destination but return immediately to the caller.
****************************************************/
public void transfer() {

  transfer(-1);
}


/***************************************************
* Determine the object's current state. Returns one
* of the class constants.
****************************************************/
public int getState() {

  return state;
}

/***************************************************
* Returns the object's state as a String. A more
* user friendly version of getState().
****************************************************/
public String getStateName() {

  return STATE_NAMES[state];
}

/***************************************************
* Obtain the rate being used for the process. This
* is often 1, despite what the user may have supplied
* as Clocks (hence Processors) don't have to support
* any other rate than 1 (and will default to that).
****************************************************/
public float getRate() {

  return translationRate;
}

/***************************************************
* Set the time at which media processing will stop.
* Specification is in media time. This means only
* the first "when" amount of the media will be
* transferred.
****************************************************/
public void setStopTime(Time when) {

  if (processor!=null)
    processor.setStopTime(when);
}

/***************************************************
* Stop the processing and hence transfer. This
* gives user control over the duration of a
* transfer. It could be started with the transfer()
* call and after a specified period stop() could
* be called.
****************************************************/
public void stop() {

  if (processor!=null)
    processor.stop();
}
}

Thanx a lot in advance.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.