Hello,

In my project I have to capture screen activity (including audio) to a video file. I try using JMF for this. I don't know how to use those two classes: DataSource.java and LiveStream.java. I read them line by line. I probably have to create a Processor and feed it with that DataSource. Can someone give me a hint? Or CODE? I read a lot of examples but I couldn't understand yet how to create a screen-captur using JMF and save it to disk.
The two classes:

//DataSource

import javax.media.Time;
import javax.media.protocol.*;
import java.io.IOException;

/**
 * This DataSource captures live frames from the screen.
 * You can specify the location, size and frame rate in the
 * URL string as follows:
 * screen://x,y,width,height/framespersecond
 * Eg:
 *    screen://20,40,160,120/12.5
 * Note:
 *    Requires JDK 1.3+ to compile and run
 */

public class DataSource extends PushBufferDataSource {

    protected Object [] controls = new Object[0];
    protected boolean started = false;
    protected String contentType = "raw";
    protected boolean connected = false;
    protected Time duration = DURATION_UNBOUNDED;
    protected LiveStream [] streams = null;
    protected LiveStream stream = null;
    
    public DataSource() {
    }
    
    public String getContentType() {
	if (!connected){
            System.err.println("Error: DataSource not connected");
            return null;
        }
	return contentType;
    }

    public void connect() throws IOException {
	 if (connected)
            return;
	 connected = true;
    }

    public void disconnect() {
	try {
            if (started)
                stop();
        } catch (IOException e) {}
	connected = false;
    }

    public void start() throws IOException {
	// we need to throw error if connect() has not been called
        if (!connected)
            throw new java.lang.Error("DataSource must be connected before it can be started");
        if (started)
            return;
	started = true;
	stream.start(true);
    }

    public void stop() throws IOException {
	if ((!connected) || (!started))
	    return;
	started = false;
	stream.start(false);
    }

    public Object [] getControls() {
	return controls;
    }

    public Object getControl(String controlType) {
	return null;
    }

    public Time getDuration() {
	return duration;
    }

    public PushBufferStream [] getStreams() {
	if (streams == null) {
	    streams = new LiveStream[1];
	    stream = streams[0] = new LiveStream(getLocator());
	}
	return streams;
    }
}
//LiveStream - this takes snapshots and feeds it to DataSource

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import java.io.IOException;
import java.util.StringTokenizer;

public class LiveStream implements PushBufferStream, Runnable {

    protected ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW);
    protected int maxDataLength;
    protected int [] data;
    protected Dimension size;
    protected RGBFormat rgbFormat;
    protected boolean started;
    protected Thread thread;
    protected float frameRate = 1f;
    protected BufferTransferHandler transferHandler;
    protected Control [] controls = new Control[0];
    protected int x, y, width, height;

    protected Robot robot = null;

    public LiveStream(MediaLocator locator) {
	try {
	    parseLocator(locator);
	} catch (Exception e) {
	    System.err.println(e);
	}
	//size = Toolkit.getDefaultToolkit().getScreenSize();
	size = new Dimension(width, height);
	try {
	    robot = new Robot();
	} catch (AWTException awe) {
	    throw new RuntimeException("");
	}
	maxDataLength = size.width * size.height * 3;
	rgbFormat = new RGBFormat(size, maxDataLength,
				  Format.intArray,
				  frameRate,
				  32,
				  0xFF0000, 0xFF00, 0xFF,
				  1, size.width,
				  VideoFormat.FALSE,
				  Format.NOT_SPECIFIED);
	
	// generate the data
	data = new int[maxDataLength];
	thread = new Thread(this, "Screen Grabber");
    }

    protected void parseLocator(MediaLocator locator) {
        // this parses the locator. e.g.: screen://x,y,width,height/fps
	String rem = locator.getRemainder();
	// Strip off starting slashes
	while (rem.startsWith("/") && rem.length() > 1)
	    rem = rem.substring(1);
	StringTokenizer st = new StringTokenizer(rem, "/");
	if (st.hasMoreTokens()) {
	    // Parse the position
	    String position = st.nextToken();
	    StringTokenizer nums = new StringTokenizer(position, ",");
	    String stX = nums.nextToken();
	    String stY = nums.nextToken();
	    String stW = nums.nextToken();
	    String stH = nums.nextToken();
	    x = Integer.parseInt(stX);
	    y = Integer.parseInt(stY);
	    width = Integer.parseInt(stW);
	    height = Integer.parseInt(stH);
	}
	if (st.hasMoreTokens()) {
	    // Parse the frame rate
	    String stFPS = st.nextToken();
	    frameRate = (Double.valueOf(stFPS)).floatValue();
	}
    }
    
    /***************************************************************************
     * SourceStream
     ***************************************************************************/
    
    public ContentDescriptor getContentDescriptor() {
	return cd;
    }

    public long getContentLength() {
	return LENGTH_UNKNOWN;
    }

    public boolean endOfStream() {
	return false;
    }

    /***************************************************************************
     * PushBufferStream
     ***************************************************************************/

    int seqNo = 0;
    
    public Format getFormat() {
	return rgbFormat;
    }

    public void read(Buffer buffer) throws IOException {
	synchronized (this) {
	    Object outdata = buffer.getData();
	    if (outdata == null || !(outdata.getClass() == Format.intArray) ||
		((int[])outdata).length < maxDataLength) {
		outdata = new int[maxDataLength];
		buffer.setData(outdata);
	    }
	    buffer.setFormat( rgbFormat );
	    buffer.setTimeStamp( (long) (seqNo * (1000 / frameRate) * 1000000) );
	    BufferedImage bi = robot.createScreenCapture(new Rectangle(x, y, width, height));
	    bi.getRGB(0, 0, width, height,
		      (int[])outdata, 0, width);
	    buffer.setSequenceNumber( seqNo );
	    buffer.setLength(maxDataLength);
	    buffer.setFlags(Buffer.FLAG_KEY_FRAME);
	    buffer.setHeader( null );
	    seqNo++;
	}
    }

    public void setTransferHandler(BufferTransferHandler transferHandler) {
	synchronized (this) {
	    this.transferHandler = transferHandler;
	    notifyAll();
	}
    }

    void start(boolean started) {
	synchronized ( this ) {
	    this.started = started;
	    if (started && !thread.isAlive()) {
		thread = new Thread(this);
		thread.start();
	    }
	    notifyAll();
	}
    }

    /***************************************************************************
     * Runnable
     ***************************************************************************/

    public void run() {
	while (started) {
	    synchronized (this) {
		while (transferHandler == null && started) {
		    try {
			wait(1000);
		    } catch (InterruptedException ie) {
		    }
		} // while
	    }

	    if (started && transferHandler != null) {
		transferHandler.transferData(this);
		try {
		    Thread.currentThread().sleep( 10 );
		} catch (InterruptedException ise) {
		}
	    }
	} // while (started)
    } // run

    // Controls
    
    public Object [] getControls() {
	return controls;
    }

    public Object getControl(String controlType) {
       try {
          Class  cls = Class.forName(controlType);
          Object cs[] = getControls();
          for (int i = 0; i < cs.length; i++) {
             if (cls.isInstance(cs[i]))
                return cs[i];
          }
          return null;

       } catch (Exception e) {   // no such controlType or such control
         return null;
       }
    }
}

Some other resources:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules/java-3d/com/db/layers/underlay/Capturer.java.htm

(I read about screen graber and all those sun examples and I googled so much... spent days...)
I didn't find a full example that captures the screen to a video file yet. Somebody help please? I would apreciate it so much...

This article has been dead for over six months. Start a new discussion instead.