Xuggle和java库路径
我正在用Java编写截屏video应用程序。 我决定使用Xuggle来做这件事,然后我跟着xuggle wiki上的安装说明。
我使用%XUGGLE_HOME%\ bin和%XUGGLE_HOME%\ lib设置了PATH环境。 一切似乎都好。 我把这个应用程序作为RCP插件。 我在“RCP-mail”模板上试了一下,插件正常工作,video生成正确。
但是,当我决定在“真正的”应用程序上使用它时,插件崩溃了一个奇怪的错误消息:
开始捕获
2011-11-10 08:08:45,438 [Thread-5] WARN com.xuggle.ferry.JNILibraryLoader – 失败:库的库加载:xuggle-xuggler; version:3:绝对路径:C:\ Program Files(x86)\ Xuggle \ bin \ libxuggle-xuggler-3.dll; 错误:java.lang.UnsatisfiedLinkError:C:\ Program Files(x86)\ Xuggle \ bin \ libxuggle-xuggler-3.dll:找不到依赖库
2011-11-10 08:08:45,447 [Thread-5] WARN com.xuggle.ferry.JNILibraryLoader – 失败:库的库加载:xuggle-xuggler; version:3:绝对路径:C:\ Program Files(x86)\ Xuggle \ bin \ libxuggle-xuggler-3.dll; 错误:java.lang.UnsatisfiedLinkError:C:\ Program Files(x86)\ Xuggle \ bin \ libxuggle-xuggler-3.dll:找不到依赖库
2011-11-10 08:08:45,453 [Thread-5] ERROR com.xuggle.ferry.JNILibraryLoader – 无法加载库:xuggle-xuggler; 版本:3; 请访问http://www.xuggle.com/xuggler/faq/以查找此问题的常见解决方案
但这很奇怪,因为java.library.path定义得很好:
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)的事实吗?
以下是用于制作截屏video的代码:
RecordHandler.java: private void startRecording() { Logger logger = Logger.getLogger(RecordHandler.class.getName()); logger.info(System.getProperty("java.library.path")); // Initialize framesQueue framesQueue = new LinkedBlockingQueue(); // 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(); }
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) { } } } }); }
FrameEncoder.java:
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 frames = new LinkedList(); 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(); }
我知道这有点晚了,但问题是Xuggler要求所有的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
- java.io.FileNotFoundException :(没有这样的文件或目录)从eclipse运行时
- 如果将google-play-services.jar lib添加到Eclipse中的helloworld android项目中,Android编译会冻结
- JLabel的KeyListener对我不起作用
- 如何使用Eclipse创建’testng.xml’
- bluej接口的eclipse插件
- Eclipse与CVS存储库同步时是否可以忽略.cvsignore文件?
- 将Java项目从GitHub导入Eclipse
- 我想从包资源管理器中检索所选java文件的路径/文件名
- 从头开始构建Eclipse IDE – 如何在JDT上选择CDT?