Xuggle和java库路径
我正在用Java编写一个屏幕广播应用程序。 我决定使用Xuggle来完成这项工作,并按照XuggleWiki上的安装说明进行操作 我使用%XUGGLE\u HOME%\bin和%XUGGLE\u HOME%\lib设置了路径环境。一切似乎都很好。 我把这个应用程序作为一个RCP插件。我在“RCP邮件”模板上尝试了它,插件正在工作,视频生成正确 但当我决定在“真正”的应用程序上使用它时,插件崩溃了,并显示一条奇怪的错误消息: 开始捕获 2011-11-10 08:08:45438[Thread-5]WARN com.xuggle.ferry.JNILibraryLoader-故障:库的库加载:xuggle xuggler;版本:3:绝对路径:C:\ProgramFiles(x86)\Xuggle\bin\libxuggle-xuggler-3.dll;错误:java.lang.UnsatisfiedLink错误:C:\Program Files(x86)\Xuggle\bin\libxuggle-xuggler-3.dll:找不到依赖库 2011-11-10 08:08:45447[Thread-5]WARN com.xuggle.ferry.JNILibraryLoader-故障:库的库加载:xuggle xuggler;版本:3:绝对路径:C:\ProgramFiles(x86)\Xuggle\bin\libxuggle-xuggler-3.dll;错误:java.lang.UnsatisfiedLink错误:C:\Program Files(x86)\Xuggle\bin\libxuggle-xuggler-3.dll:找不到依赖库 2011-11-10 08:08:45453[Thread-5]错误com.xuggle.ferry.JNILibraryLoader-无法加载库:xuggle xuggler;版本:3;访问以找到此问题的常见解决方案 但这很奇怪,因为java.library.path定义得很好:Xuggle和java库路径,java,eclipse,configuration,rcp,xuggle,Java,Eclipse,Configuration,Rcp,Xuggle,我正在用Java编写一个屏幕广播应用程序。 我决定使用Xuggle来完成这项工作,并按照XuggleWiki上的安装说明进行操作 我使用%XUGGLE\u HOME%\bin和%XUGGLE\u HOME%\lib设置了路径环境。一切似乎都很好。 我把这个应用程序作为一个RCP插件。我在“RCP邮件”模板上尝试了它,插件正在工作,视频生成正确 但当我决定在“真正”的应用程序上使用它时,插件崩溃了,并显示一条奇怪的错误消息: 开始捕获 2011-11-10 08:08:45438[Thread-5
logger.info(System.getProperty("java.library.path"));
返回
Nov 10, 2011 8:08:45 AM com.gvs.tools.ui.record.video.handler.RecordHandler startRecording
INFO: C:\Program Files (x86)\Java\jre6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files (x86)/Java/jre6/bin/client;C:/Program Files (x86)/Java/jre6/bin;C:/Program Files (x86)/Java/jre6/lib/i386;C:\Program Files (x86)\Xuggle\bin;C:\Program Files (x86)\Xuggle\lib;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\JProbe 8.3\bin;C:\Program Files\TortoiseSVN\bin;D:\Work\Paul\eclipse;;.
要使插件与此应用程序一起工作,我缺少了什么?
此问题是否是由于应用程序使用其他本机库(如3D dll)造成的
以下是用于制作screencast视频的代码:
RecordHandler.java:
private void startRecording() {
Logger logger = Logger.getLogger(RecordHandler.class.getName());
logger.info(System.getProperty("java.library.path"));
// Initialize framesQueue
framesQueue = new LinkedBlockingQueue<BufferedImage>();
// Initialize the capture thread
captureThread = new ScreenCapturer();
captureThread.setCaptureFramesQueue(framesQueue);
// Initialize the recorder
encoderThread = new FrameEncoder("test.mp4");
encoderThread.setCapturedFramesQueue(framesQueue);
// Start capture
captureThread.start();
// wait for the Queue to be feed before encoding
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
}
encoderThread.start();
}
RecordHandler.java:
私有无效开始记录(){
Logger=Logger.getLogger(RecordHandler.class.getName());
info(System.getProperty(“java.library.path”);
//初始化帧队列
framesQueue=新建LinkedBlockingQueue();
//初始化捕获线程
capturatRead=新屏幕捕获器();
setCaptureFramesQueue(framesQueue);
//初始化记录器
encoderThread=新的帧编码器(“test.mp4”);
encoderRead.setCapturedFramesQueue(framesQueue);
//开始捕获
captRead.start();
//在编码之前,等待队列被馈送
试一试{
睡眠(1000L);
}捕捉(中断异常e){
}
encoderThread.start();
}
ScreenCapturer.java:
@Override
public void run() {
// Retrieve the application main window's shell
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
appShell = Display.getCurrent().getActiveShell();
}
});
isRunning = true;
System.out.println("Starting Capture");
for (numberOfFramesTaken = 0; isRunning && numberOfFramesTaken <= IVideoEncoderConfiguration.MAXIMUM_NUMBER_OF_FRAMES; numberOfFramesTaken++) {
try {
takeScreenShot();
Thread.sleep(IVideoEncoderConfiguration.CAPTURE_TIME_INTERVAL_MILLIS);
} catch (InterruptedException e) {
}
}
System.out.println("Capture has ended");
System.out.println("Number of frames taken: "
+ numberOfFramesTaken);
}
/**
* Take a screen capture and store it in the capturedFramesQueue
*/
private void takeScreenShot() {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (appShell != null) {
Rectangle bounds = appShell.getBounds();
java.awt.Rectangle awtBounds = new java.awt.Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
final BufferedImage screenCapture = robot.createScreenCapture(awtBounds);
try {
capturedFramesQueue.put(screenCapture);
} catch (InterruptedException e) {
}
}
}
});
}
@覆盖
公开募捐{
//检索应用程序主窗口的外壳
Display.getDefault().asyncExec(新的Runnable()){
@凌驾
公开募捐{
appShell=Display.getCurrent().getActiveShell();
}
});
isRunning=true;
System.out.println(“开始捕获”);
对于(numberOfFramesTaken=0;正在运行&&numberOfFramesTaken,我知道有点晚了,但问题是Xugler要求所有DLL都位于操作系统加载路径环境中,而不仅仅是java.library.path
这意味着使用Xuggle安装的所有dll(例如libavcodec.dll)都需要位于启动Java的进程的%PATH%环境变量中。原因可能是依赖项jar不可用或版本冲突
在类路径中添加以下JAR对我来说效果很好:
xuggle-xuggler-5.4.jar
slf4j-api-1.6.4.jar
logback-core-1.0.0.jar
logback-classic-1.0.0.jar
public void run() {
isRunning = true;
String outFile = outputdirectoryPath + outputFileName;
// First, let's make a IMediaWriter to write the file.
final IMediaWriter writer = ToolFactory.makeWriter(outFile);
// Retrieve the first frame to guess video dimensions
BufferedImage firstFrame = null;
try {
firstFrame = capturedFramesQueue.take();
} catch (InterruptedException e) {
}
if (firstFrame == null) {
return;
}
// We tell it we're going to add one video stream, with id 0,
// at position 0, and that it will have a fixed frame rate of
// FRAME_RATE.
writer.addVideoStream(0, 0,
IVideoEncoderConfiguration.FRAME_RATE,
firstFrame.getWidth(), firstFrame.getHeight());
long startTime = System.nanoTime();
for (numberOfFramesRecorded = 0; isRunning
&& numberOfFramesRecorded <= IVideoEncoderConfiguration.MAXIMUM_NUMBER_OF_FRAMES; numberOfFramesRecorded++) {
// Retrieve the captured frame
try {
final BufferedImage currentFrame = convertToType(capturedFramesQueue.take(), BufferedImage.TYPE_3BYTE_BGR);
// encode the next frame
writer.encodeVideo(0, currentFrame, System.nanoTime() - startTime,
TimeUnit.NANOSECONDS);
// sleep, time depending of FRAME_RATE
Thread.sleep(IVideoEncoderConfiguration.CAPTURE_TIME_INTERVAL_MILLIS);
} catch (InterruptedException e) {
}
}
// Get the remaining frame on the queue
Collection<BufferedImage> frames = new LinkedList<BufferedImage>();
capturedFramesQueue.drainTo(frames, IVideoEncoderConfiguration.MAXIMUM_NUMBER_OF_FRAMES - numberOfFramesRecorded);
for (BufferedImage frame : frames) {
BufferedImage currentFrame = convertToType(frame, BufferedImage.TYPE_3BYTE_BGR);
writer.encodeVideo(0, currentFrame, System.nanoTime() - startTime,
TimeUnit.NANOSECONDS);
}
// close the MediaWriter, write the trailer if needed
writer.close();
}