Olás,
alguém já conseguiu realizar essa façanha?
Em particular, o seguinte código não funciona.
Se utilizarmos mp.setMediaTime o código funciona parcialmente.
Por exemplo, para frameNumber variando de 1 a 18, obtemos (surpreendentemente?) o 1º frame como resposta. A partir do frame 19 até (37?) obtemos o frame 19 como resposta. Estou esquecendo algo aqui ou o JMF está morto mesmo, cheio de bugs e inutilizável?
package main;
import javax.imageio.ImageIO;
import javax.media.*;
import javax.media.control.FrameGrabbingControl;
import javax.media.control.FramePositioningControl;
import javax.media.control.FrameRateControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* Date: 06/05/2005
* Time: 16:56:49
*
* @author Filipe Silva
*/
public class Main implements ControllerListener {
private FrameGrabbingControl grabber;
private FrameRateControl fps;
private FramePositioningControl fpc;
private Player mp;
private BooleanLocker lock;
private boolean firstTime;
public Main() {
try {
Manager.setHint(Manager.PLUGIN_PLAYER, new Boolean(true));
mp = Manager.createPlayer(new MediaLocator("file:///vid1.mpg"));
} catch (NoPlayerException npe) {
npe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
grabber = null;
fps = null;
fpc = null;
lock = new BooleanLocker();
firstTime = true;
mp.addControllerListener(this);
mp.realize();
mp.prefetch();
}
public static void main(String[] args) {
new Main();
}
public void controllerUpdate(ControllerEvent event) {
if (event instanceof PrefetchCompleteEvent) {
if (firstTime) {
if (grabber == null) {
grabber = (FrameGrabbingControl) mp.getControl("javax.media.control.FrameGrabbingControl");
if (grabber == null) {
System.out.println("Num tem grabber");
System.exit(-1);
}
}
if (fps == null) {
fps = (FrameRateControl) mp.getControl("javax.media.control.FrameRateControl");
if (fps == null) {
System.out.println("num tem fps");
System.exit(-1);
}
}
if (fpc == null) {
fpc = (FramePositioningControl) mp.getControl("javax.media.control.FramePositioningControl");
if (fpc == null) {
System.out.println("num tem framePositioning");
System.exit(-1);
}
}
firstTime = false;
new FrameGrabberThread(grabber, fps, fpc, mp, lock).start();
} else {
synchronized (lock) {
lock.canGrab = true;
}
}
}
}
}
class BooleanLocker {
public boolean canGrab;
public BooleanLocker() {
canGrab = false;
}
}
class FrameGrabberThread extends Thread {
private FrameGrabbingControl grabber;
private FrameRateControl fps;
private FramePositioningControl fpc;
private Player mp;
private Buffer buffer;
private VideoFormat vFormat;
private BufferToImage bToImage;
private BufferedImage image;
private BooleanLocker lock;
private static final long WAIT = 100;
public FrameGrabberThread(FrameGrabbingControl grabber, FrameRateControl fps, FramePositioningControl fpc, Player mp, BooleanLocker lock) {
this.grabber = grabber;
this.fps = fps;
this.mp = mp;
this.lock = lock;
this.fpc = fpc;
}
public void run() {
int frameNumber = 19;
synchronized (lock) {
lock.canGrab = false;
}
fpc.seek(frameNumber);
mp.prefetch();
long t = System.currentTimeMillis();
synchronized (lock) {
while (!lock.canGrab && System.currentTimeMillis() < t + WAIT)
try {
lock.wait(1);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
if (System.currentTimeMillis() >= t + WAIT) {
System.out.println("deadlock ou sei lá ta demorando muito");
System.exit(-1);
}
}
synchronized (lock) {
if (!lock.canGrab) {
System.out.println("O lock não foi locado. Abortando");
System.exit(-1);
}
}
buffer = grabber.grabFrame();
vFormat = (VideoFormat) buffer.getFormat();
bToImage = new BufferToImage(vFormat);
image = (BufferedImage) bToImage.createImage(buffer);
File f;
if (frameNumber < 10)
f = new File("c:" + File.separator + "teste" + File.separator + "frame0" + frameNumber + ".jpg");
else
f = new File("c:" + File.separator + "teste" + File.separator + "frame" + frameNumber + ".jpg");
try {
ImageIO.write(image, "jpeg", f);
} catch (IOException ioe) {
ioe.printStackTrace();
}
mp.close();
}
}