continua...................
Questa è la classe che viene chiamata per realizzare il video
codice:
----------------------------------------------------------------------------------------
import java.io.*;
import java.util.*;
import java.awt.Dimension;
import javax.media.*;
import javax.media.control.*;
import javax.media.protocol.*;
import javax.media.protocol.DataSource;
import javax.media.datasink.*;
import javax.media.format.VideoFormat;
/**
* Questo programma prende una sequenza di immagini JPEG e le converte in un
* file video QuickTime.
*/
public class generaVideo implements ControllerListener,
DataSinkListener {
public boolean doIt(int width, int height, int frameRate, Vector inFiles,
MediaLocator outML) {
ImageDataSource ids = new ImageDataSource(width, height, frameRate,
inFiles);
Processor p;
try {
System.err.println("Creazione del processor dal datasource…");
p = Manager.createProcessor(ids);
} catch (Exception e) {
System.err.println("Impossibile creare un processor dal " +
"datasource!");
return false;
}
p.addControllerListener(this);
// Mettiamo il Processor nello stato configurato in modo da poter
// settare le opzioni del Processor
p.configure();
if (!waitForState(p, p.Configured)) {
System.err.println("Configurazione del Processor fallita.");
return false;
}
// Poniamo l'uscita del Processor di tipo QuickTime.
p.setContentDescriptor(new ContentDescriptor(
FileTypeDescriptor.QUICKTIME));
// Settiamo il formato della traccia
TrackControl tcs[] = p.getTrackControls();
Format f[] = tcs[0].getSupportedFormats();
if (f == null || f.length <= 0) {
System.err.println("Questo formato non è supportato: "
+ tcs[0].getFormat());
return false;
}
tcs[0].setFormat(f[0]);
System.err.println("Il formato settato della traccia è: " + f[0]);
// Realizziamo il Processor
p.realize();
if (!waitForState(p, p.Realized)) {
System.err.println("Realizzazione del Processor fallita.");
return false;
}
// Creiamo il DataSink
DataSink dsink;
if ((dsink = createDataSink(p, outML)) == null) {
System.err.println("Creazione del DataSink fallita per il " +
"MediaLocator: " + outML);
return false;
}
dsink.addDataSinkListener(this);
fileDone = false;
System.err.println("Avviata la transcodifica..");
// Avviamo il processo di transcodifica
try {
p.start();
dsink.start();
} catch (IOException e) {
System.err.println("Errore di IO durante la transcodifica.");
return false;
}
waitForFileDone();
try {
dsink.close();
} catch (Exception e) {
}
p.removeControllerListener(this);
System.err.println("...transcodifica terminata.");
return true;
}
/**
* Creazione del DataSink
*/
DataSink createDataSink(Processor p, MediaLocator outML) {
DataSource ds;
if ((ds = p.getDataOutput()) == null) {
System.err.println("Il Processor non ha un DataSource di " +
"output. ");
return null;
}
DataSink dsink;
try {
System.err.println("DataSink creato per il MediaLocator: "
+ outML);
dsink = Manager.createDataSink(ds, outML);
dsink.open();
} catch (Exception e) {
System.err.println("Impossibile creare il DataSink: " + e);
return null;
}
return dsink;
}
Object waitSync = new Object();
boolean stateTransitionOK = true;
/**
* Aspetta finché il Processor non è transitato nello stato desiderato.
* Ritorna false se la transizione è fallita.
*/
boolean waitForState(Processor p, int state) {
synchronized (waitSync) {
try {
while (p.getState() < state && stateTransitionOK)
waitSync.wait();
} catch (Exception e) {
}
}
return stateTransitionOK;
}
/**
* Controller Listener.
*/
public void controllerUpdate(ControllerEvent evt) {
if (evt instanceof ConfigureCompleteEvent
|| evt instanceof RealizeCompleteEvent
|| evt instanceof PrefetchCompleteEvent) {
synchronized (waitSync) {
stateTransitionOK = true;
waitSync.notifyAll();
}
} else if (evt instanceof ResourceUnavailableEvent) {
synchronized (waitSync) {
stateTransitionOK = false;
waitSync.notifyAll();
}
} else if (evt instanceof EndOfMediaEvent) {
evt.getSourceController().stop();
evt.getSourceController().close();
}
}
Object waitFileSync = new Object();
boolean fileDone = false;
boolean fileSuccess = true;
/**
* Aspetta finché non è terminata la scrittura del file.
*/
boolean waitForFileDone() {
synchronized (waitFileSync) {
try {
while (!fileDone)
waitFileSync.wait();
} catch (Exception e) {
}
}
return fileSuccess;
}
/**
* Gestore degli eventi del file writer.
*/
public void dataSinkUpdate(DataSinkEvent evt) {
if (evt instanceof EndOfStreamEvent) {
synchronized (waitFileSync) {
fileDone = true;
waitFileSync.notifyAll();
}
} else if (evt instanceof DataSinkErrorEvent) {
synchronized (waitFileSync) {
fileDone = true;
fileSuccess = false;
waitFileSync.notifyAll();
}
}
}
public static void creaVideo(){
int width = -1, height = -1, frameRate = 1;
Vector inputFiles = new Vector();
String outputURL = null;
width =1024;
height=768;
frameRate=3;
outputURL="file://c:/video/video.mov";
int i=0;
while(i<50){
inputFiles.addElement("c:/image/screencapture"+i+".png");
i++;
}
if (outputURL == null || inputFiles.size() == 0)
prUsage();
// Controlla l'estensione del file video desiderato.
if (!outputURL.endsWith(".mov") && !outputURL.endsWith(".MOV")) {
System.err.println("L'estensione del file video dovrebbe " +
"essere .mov");
prUsage();
}
if (width < 0 || height < 0) {
System.err.println("Specificare la corretta dimensione dell'"
+ "immagine");
prUsage();
}
// Controlla il frame rate.
if (frameRate < 1)
frameRate = 1;
// Genera il media locator .
MediaLocator oml;
if ((oml = createMediaLocator(outputURL)) == null) {
System.err.println("Impossibile creare il Media Locator: "
+ outputURL);
System.exit(0);
}
generaVideo imgToMovie = new
generaVideo();
imgToMovie.doIt(width, height, frameRate, inputFiles, oml);
System.exit(0);
}
static void prUsage() {
System.err.println("Come avviare il programma: " +
"java GeneratingVideoFromImages -w " +
" <width> -h <height> -f <frame rate> " +
"-o <output URL> <input JPEG file 1> " +
"<input JPEG file 2> ...");
System.exit(-1);
}
/**
* Crea un MediaLocator a partire dalla url passatagli come argomento
*/
static MediaLocator createMediaLocator(String url) {
MediaLocator ml;
if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null)
return ml;
if (url.startsWith(File.separator)) {
if ((ml = new MediaLocator("file:" + url)) != null)
return ml;
} else {
String file = "file:" + System.getProperty("user.dir")
+ File.separator + url;
System.out.println("---------->FILE: "+file);
if ((ml = new MediaLocator(file)) != null)
return ml;
}
return null;
}
/**
* Un DataSource per leggere i dati da una sequenza di file immagini JPEG
* e memorizzarli in uno stream di buffer.
*/
class ImageDataSource extends PullBufferDataSource {
ImageSourceStream streams[];
ImageDataSource(int width, int height, int frameRate, Vector images)
{
streams = new ImageSourceStream[1];
streams[0] = new ImageSourceStream(width, height, frameRate,
images);
}
public void setLocator(MediaLocator source) {
}
public MediaLocator getLocator() {
return null;
}
public String getContentType() {
return ContentDescriptor.RAW;
}
public void connect() {
}
public void disconnect() {
}
public void start() {
}
public void stop() {
}
public PullBufferStream[] getStreams() {
return streams;
}
public Time getDuration() {
return DURATION_UNKNOWN;
}
public Object[] getControls() {
return new Object[0];
}
public Object getControl(String type) {
return null;
}
}
/**
* Lo stream sorgente per scorrere l'ImageDataSource.
*/
class ImageSourceStream implements PullBufferStream {
Vector images;
int width, height;
VideoFormat format;
float frameRate;
long seqNo = 0;
// indice della prossima immagine da leggere.
int nextImage = 0;
boolean ended = false;
public ImageSourceStream(int width, int height, int frameRate,
Vector images) {
this.width = width;
this.height = height;
this.images = images;
this.frameRate = (float) frameRate;
format = new VideoFormat(VideoFormat.JPEG,
new Dimension(width,height), Format.NOT_SPECIFIED, Format.byteArray,frameRate);
}
public boolean willReadBlock() {
return false;
}
/**
* Legge i frame del video.
*/
public void read(Buffer buf) throws IOException {
if (nextImage >= images.size()) {
System.err.println("Lette tutte le immagini.");
buf.setEOM(true);
buf.setOffset(0);
buf.setLength(0);
ended = true;
return;
}
String imageFile = (String) images.elementAt(nextImage);
nextImage++;
System.err.println("Lettura del file: " + imageFile);
// Apriamo un random access file per la prossima immagine.
RandomAccessFile raFile;
raFile = new RandomAccessFile(imageFile, "r");
byte data[] = null;
if (buf.getData() instanceof byte[])
data = (byte[]) buf.getData();
if (data == null || data.length < raFile.length()) {
data = new byte[(int) raFile.length()];
buf.setData(data);
}
long time = (long) (seqNo * (1000 / frameRate) * 1000000);
buf.setTimeStamp(time);
buf.setSequenceNumber(seqNo++);
raFile.readFully(data, 0, (int) raFile.length());
buf.setOffset(0);
buf.setLength((int) raFile.length());
buf.setFormat(format);
buf.setFlags(buf.getFlags() | buf.FLAG_KEY_FRAME);
raFile.close();
}
/**
* Ritorna il formato dell'immagine...che sarà JPEG
*/
public Format getFormat() {
return format;
}
public ContentDescriptor getContentDescriptor() {
return new ContentDescriptor(ContentDescriptor.RAW);
}
public long getContentLength() {
return 0;
}
public boolean endOfStream() {
return ended;
}
public Object[] getControls() {
return new Object[0];
}
public Object getControl(String type) {
return null;
}
}
}
e la pagina che richiama l'applet è :
codice:
<applet code="mainApplet.class" archive="Sscreenshot-applet.jar,jmf.jar" name="main" width="120" height="60" mayscript>
Attenzione: Devi abilitare le Applet!</applet>
<input type="button" name="start" value="start" onclick="document.main.startFoto();" />
<input type="button" name="stop" value="stop" onclick="document.main.stopFoto();" />