下面的代码用于基于图像列表生成的视频。目的是基于所选文件夹上的图像创建缩时视频。因此,这是负责制作视频的班级
public class AviCreator implements ControllerListener, DataSinkListener
{
private boolean doIt(
int width,
int height,
int frameRate,
MediaLocator outML)
{
ImageDataSource ids = new ImageDataSource(width, height, frameRate);
Processor p;
try
{
System.err.println(
"- create processor for the image datasource ...");
p = Manager.createProcessor(ids);
}
catch (Exception e)
{
System.err.println(
"Yikes! Cannot create a processor from the data source.");
return false;
}
p.addControllerListener(this);
// Put the Processor into configured state so we can set
// some processing options on the processor.
p.configure();
if (!waitForState(p, Processor.Configured))
{
System.err.println("Failed to configure the processor.");
return false;
}
// Set the output content descriptor to QuickTime.
p.setContentDescriptor(
new ContentDescriptor(FileTypeDescriptor.MSVIDEO));
// Query for the processor for supported formats.
// Then set it on the processor.
TrackControl tcs[] = p.getTrackControls();
Format f[] = tcs[0].getSupportedFormats();
if (f == null || f.length <= 0)
{
System.err.println(
"The mux does not support the input format: "
+ tcs[0].getFormat());
return false;
}
tcs[0].setFormat(f[0]);
System.err.println("Setting the track format to: " + f[0]);
// We are done with programming the processor. Let's just
// realize it.
p.realize();
if (!waitForState(p, Processor.Realized))
{
System.err.println("Failed to realize the processor.");
return false;
}
// Now, we'll need to create a DataSink.
DataSink dsink;
if ((dsink = createDataSink(p, outML)) == null)
{
System.err.println(
"Failed to create a DataSink for the given output MediaLocator: "
+ outML);
return false;
}
dsink.addDataSinkListener(this);
fileDone = false;
System.err.println("start processing...");
// OK, we can now start the actual transcoding.
try
{
p.start();
dsink.start();
}
catch (IOException e)
{
System.err.println("IO error during processing");
return false;
}
// Wait for EndOfStream event.
waitForFileDone();
// Cleanup.
try
{
dsink.close();
}
catch (Exception e)
{
}
p.removeControllerListener(this);
System.err.println("...done processing.");
return true;
}
/**
* Create the DataSink.
*/
private DataSink createDataSink(Processor p, MediaLocator outML)
{
DataSource ds;
if ((ds = p.getDataOutput()) == null)
{
System.err.println(
"Something is really wrong: the processor does not have an output DataSource");
return null;
}
DataSink dsink;
try
{
System.err.println("- create DataSink for: " + outML);
dsink = Manager.createDataSink(ds, outML);
dsink.open();
}
catch (Exception e)
{
System.err.println("Cannot create the DataSink: " + e);
return null;
}
return dsink;
}
private Object waitSync = new Object();
private boolean stateTransitionOK = true;
/**
* Block until the processor has transitioned to the given state.
* Return false if the transition failed.
*/
private 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();
}
}
private Object waitFileSync = new Object();
private boolean fileDone = false;
private boolean fileSuccess = true;
/**
* Block until file writing is done.
*/
private boolean waitForFileDone()
{
synchronized (waitFileSync)
{
try
{
while (!fileDone)
waitFileSync.wait();
}
catch (Exception e)
{
}
}
return fileSuccess;
}
/**
* Event handler for the 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();
}
}
}
每次我尝试从全高清图像创建全高清视频时,我总是卡在功能waitForFileDone()
上。或者,如果成功,则制作全高清视频需要一个小时。在正常的视频分辨率下,它可以正常工作。还有其他方法比等待流事件结束更快吗?