Путь к библиотеке Xuggle и Java

Я пишу приложение для скринкаста на Java. Я решил использовать Xuggle для этого и следовал инструкциям по установке на xuggle wiki.

Я установил среду PATH с %XUGGLE_HOME%\bin и %XUGGLE_HOME%\lib. Все кажется в порядке. Я сделал это приложение как плагин RCP. Я попробовал это на шаблоне RCP-mail, и плагин работает, и видео генерируется правильно.

Но когда я решил использовать его в реальном приложении, плагин вылетел со странным сообщением об ошибке:

Запуск захвата

10.11.2011, 08:08:45,438 [Поток-5] ПРЕДУПРЕЖДЕНИЕ com.xuggle.ferry.JNILibraryLoader — Ошибка: загрузка библиотеки из библиотеки: xuggle-xuggler; версия: 3: абсолютный путь: C:\Program Files (x86)\Xuggle\bin\libxuggle-xuggler-3.dll; ошибка: java.lang.UnsatisfiedLinkError: C:\Program Files (x86)\Xuggle\bin\libxuggle-xuggler-3.dll: не удается найти зависимые библиотеки

10.11.2011, 08:08:45,447 [Поток-5] ПРЕДУПРЕЖДЕНИЕ com.xuggle.ferry.JNILibraryLoader — Ошибка: загрузка библиотеки из библиотеки: xuggle-xuggler; версия: 3: абсолютный путь: C:\Program Files (x86)\Xuggle\bin\libxuggle-xuggler-3.dll; ошибка: java.lang.UnsatisfiedLinkError: C:\Program Files (x86)\Xuggle\bin\libxuggle-xuggler-3.dll: не удается найти зависимые библиотеки

10.11.2011, 08:08:45,453 [Поток-5] ОШИБКА 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?

Вот код, используемый для создания скринкаста:

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();
}

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) {
                }
            }
        }
    });
}

Фреймэнкодер.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<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();
}

person zeropouet    schedule 10.11.2011    source источник


Ответы (2)


Я знаю, что это немного поздно, но проблема в том, что Xuggler требует, чтобы ВСЕ библиотеки DLL находились в среде пути загрузки операционной системы, а не только в java.library.path

Это означает, что все библиотеки DLL, устанавливаемые с помощью Xuggle (например, libavcodec.dll), должны находиться в переменной окружения %PATH% процесса, запустившего Java.

person Art Clarke    schedule 21.01.2012

Причина Может быть недоступность jar-файлов зависимостей или конфликты версий.

Добавление следующих банок в путь к классу у меня отлично сработало:

xuggle-xuggler-5.4.jar slf4j-api-1.6.4.jar logback-core-1.0.0.jar logback-classic-1.0.0.jar

person AVA    schedule 06.04.2013