2016-07-05 2 views
8

Я пытаюсь захватить снимок экрана из приложения Java. Я загрузил библиотеку sarxos/webcam-capture. Я добавляю в свой проект исполняемую банку. Это немного беспорядок. Я хочу захватить видео из простого javafx-интерфейса, который я создал. Проблема в том, что после установки lib и slf4 требуется также установить xuggle. Добавить xuggle в пути, и мой код выглядит следующим образом:Захват видео с помощью веб-камеры в Java

File file = new File("output.ts"); 

IMediaWriter writer = ToolFactory.makeWriter(file.getName()); 
Dimension size = WebcamResolution.QVGA.getSize(); 

writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height); 

Webcam webcam = Webcam.getDefault(); 
webcam.setViewSize(size); 
webcam.open(true); 

long start = System.currentTimeMillis(); 

for (int i = 0; i < 50; i++) { 

    System.out.println("Capture frame " + i); 

    BufferedImage image = ConverterFactory.convertToType(webcam.getImage(), BufferedImage.TYPE_3BYTE_BGR); 
    IConverter converter = ConverterFactory.createConverter(image, IPixelFormat.Type.YUV420P); 

    IVideoPicture frame = converter.toPicture(image, (System.currentTimeMillis() - start) * 1000); 
    frame.setKeyFrame(i == 0); 
    frame.setQuality(0); 

    writer.encodeVideo(0, frame); 

    // 10 FPS 
    Thread.sleep(100); 
} 

writer.close(); 

System.out.println("Video recorded in file: " + file.getAbsolutePath()); 

Однако я получаю следующее:

Caused by: java.lang.UnsatisfiedLinkError: no xuggle-ferry in java.library.path 

EDIT2 Я также попробовал библиотеку JxCapture. Я добавляю в моем проекте все необходимые LIBS я запускаю следующий код: enter link description here, код работал отлично мне удается сохранить видео, однако в конце концов, я получаю следующее сообщение об ошибке:

8614 [JNIWrapper.ShutdownHook] ERROR com.jniwrapper.NativeResourceCollector - com.jniwrapper.FunctionExecutionException: Callback parameter types or their count are not correct at com.jniwrapper.Function.invokeVirtualFunc(Native Method)

Любая идея, что это ошибка примерно ?? Что такое JNIWrapper.ShutdownHook? Я пробовал код на трех разных машинах, и это случается только с одним из них? Как я могу обработать это исключение?

EDIT3: Я попробовал предложение @whitesite EDIT3. Гуй начал и у меня есть две кнопки запуска и остановки старт кнопки открыл камеру и, когда я попытался остановить я получил следующее:

java.lang.NullPointerException: Pointer address of argument 0 is NULL. at org.bytedeco.javacpp.opencv_videoio$VideoWriter.write(Native Method) at org.bytedeco.javacv.OpenCVFrameRecorder.record(OpenCVFrameRecorder.java:105) at Test1.lambda$0(Test1.java:52) at java.lang.Thread.run(Unknown Source)

+0

Что вы имеете в виду под "добавить xuggle в пути? Насколько я понимаю, он имеет свои собственные зависимости и нуждается в некоторых предварительно скомпилированных двоичных файлах, которые вы должны предоставить вручную, если вы не используете maven или что-то еще. – whitesite

+0

Я добавляю к своему проекту eclipse webcam-capture, затем xuggle_3.4, а затем slf4j и bridj-0.6.2. Я не знаю, что еще я должен добавить. –

+1

В принципе, ['UnsatisfiedLinkError'] (https://docs.oracle.com/javase/8/docs/api/java/lang/UnsatisfiedLinkError.html) означает, что xuggle не может найти требуемые библиотеки. Если вы прочитали [инструкции по загрузке xuggle] (http://www.xuggle.com/downloads), вы увидите, что вам нужно предоставить все его зависимости и предварительно скомпилированные двоичные файлы. Использование maven было бы намного проще. – whitesite

ответ

4

У вас не хватает slf4-Апи-ver.jar в вашем пути к классам. Однако добавление просто api не будет достаточно, вам также понадобится провайдер, например slf4j-simple-ver.jar. Последние доступны версии 1.7.21 и можно скачать здесь http://www.slf4j.org/download.html

+0

Я загрузил zip-файл, и я просто добавлю slf4j-simple-1.7.21.jar в свой проект. Тем не менее у меня такая же ошибка :(! –

+0

Вы прочитали этот https://github.com/sarxos/webcam-capture/issues/114? –

+0

Да, но все еще были ошибки. –

4

Ok, это то, что я получил с помощью этого JavaCV library и их примеры:

public class Test extends Application { 

public void start(Stage primaryStage) throws Exception { 

    OpenCVFrameGrabber capture = OpenCVFrameGrabber.createDefault(0); 
    capture.start(); 

    OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage(); 
    Java2DFrameConverter javaConverter = new Java2DFrameConverter(); 

    VBox root = new VBox(); 
    Canvas canvas = new Canvas(); 
    canvas.setHeight(capture.getImageHeight()); 
    canvas.setWidth(capture.getImageWidth()); 
    root.getChildren().add(canvas); 
    Scene scene = new Scene(root, capture.getImageWidth(), capture.getImageHeight()); 

    primaryStage.setTitle("Live video"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    Thread videoProcessor = new Thread(() -> { 
     File output = new File("C:/Work/test.avi"); 
     OpenCVFrameRecorder recorder = new OpenCVFrameRecorder(output, capture.getImageWidth(), capture.getImageHeight()); 
     try { 
      recorder.setVideoCodec(opencv_videoio.CV_FOURCC((byte) 'M', (byte) 'J', (byte) 'P', (byte) 'G')); 
      recorder.start(); 
      while (true) { 
       if(Thread.currentThread().isInterrupted()){ 
        break; 
       } 
       Frame frame = capture.grab(); 
       Platform.runLater(()->{ 
        BufferedImage image = javaConverter.getBufferedImage(frame, 1.0, false, null); 
        canvas.getGraphicsContext2D().drawImage(SwingFXUtils.toFXImage(image, null),0,0); 
       }); 
       recorder.record(frame); 
      } 
      recorder.stop(); 
      capture.release(); 
      recorder.release(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    }); 

    primaryStage.setOnCloseRequest(e->{ 
     videoProcessor.interrupt(); 
    }); 

    videoProcessor.start(); 

} 

public static void main(String[] args) throws Exception { 
    launch(args); 
} 

} 

Она захватывает видео с веб-камеры и переводит его в прямом эфире и в то же время записывает в файл. Вам нужно включить свою библиотеку в путь класса, используя maven или ручную установку, а также все банки из двоичного zip-архива. Может быть, вам не нужны все они, но я не раскопал.
Вы можете играть с настройками и исследовать примеры и источники. Из того, что я видел, это довольно мощная библиотека.
Редактировать
Просто обработка видео часть:

Thread videoProcessor = new Thread(() -> { 
     OpenCVFrameGrabber capture = null; 
     FrameRecorder recorder = null; 
     try { 

      File output = new File("C:/Work/test2.avi"); 
      capture = OpenCVFrameGrabber.createDefault(0); 
      capture.start(); 
      recorder = FrameRecorder.createDefault(output, capture.getImageWidth(), capture.getImageHeight()); 
      recorder.setFrameRate(8); 
      recorder.setVideoCodec(opencv_videoio.CV_FOURCC((byte) 'M', (byte) 'J', (byte) 'P', (byte) 'G')); 
      recorder.start(); 
      long l = System.currentTimeMillis(); 
      while (true) { 
       if(Thread.currentThread().isInterrupted()){ 
        break; 
       } 
       recorder.record(capture.grab()); 

      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       recorder.stop(); 
       capture.release(); 
       recorder.release(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

Вы должны начать процесс videoProcessor.start() где-то, а затем прервать его, чтобы остановить запись videoProcessor.interrupt(). Вам также может потребоваться установить правильную частоту кадров рекордера, чтобы настроить его на fps камеры.
Edit 2
Код для доступных устройств вывода:

int n = org.bytedeco.javacpp.videoInputLib.videoInput.listDevices(); 
for (int i = 0; i < n; i++) { 
    System.out.println(i + " = " + org.bytedeco.javacpp.videoInputLib.videoInput.getDeviceName(i)); 
} 

Редактировать 3
Если веб-камеру-захват работа, чем вы можете использовать его для захвата изображения и использовать javaCV записать эти изображения в видеофайл (в значительной степени, как exapmle в вопросе youe, просто javaCV вместо xuggler).Это небольшое JavaFX приложение, которое имеет две кнопки: «Start» начинает videoProcessing нить для захвата видео и прерывания «Stop» эту тему:

import com.github.sarxos.webcam.Webcam; 
import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import org.bytedeco.javacpp.opencv_videoio; 
import org.bytedeco.javacv.Java2DFrameConverter; 
import org.bytedeco.javacv.OpenCVFrameRecorder; 


import java.awt.Dimension; 
import java.awt.image.BufferedImage; 
import java.io.File; 

public class Test1 extends Application { 

public void start(Stage primaryStage) throws Exception { 

    final double FPS = 25; 
    final int WIDTH = 640; 
    final int HEIGHT = 480; 
    Webcam webcam = Webcam.getDefault(); 
    webcam.setViewSize(new Dimension(WIDTH, HEIGHT)); 

    Java2DFrameConverter javaConverter = new Java2DFrameConverter(); 

    VBox root = new VBox(); 
    Button b1 = new Button("Start"); 
    Button b2 = new Button("Stop"); 

    root.getChildren().addAll(b1, b2); 
    Scene scene = new Scene(root, 300,200); 
    primaryStage.setTitle("Test"); 
    primaryStage.setScene(scene); 

    Runnable r =() -> { 
     File output = new File("C:/Work/test.avi"); 
     OpenCVFrameRecorder recorder = new OpenCVFrameRecorder(output, WIDTH, HEIGHT); 
     recorder.setFrameRate(FPS); 
     try { 
      recorder.setVideoCodec(opencv_videoio.CV_FOURCC((byte) 'M', (byte) 'J', (byte) 'P', (byte) 'G')); 
      recorder.start(); 
      webcam.open(); 
      while (true) { 
       if(Thread.currentThread().isInterrupted()){ 
        break; 
       } 
       BufferedImage image = webcam.getImage(); 
       recorder.record(javaConverter.getFrame(image)); 
       try { 
        Thread.sleep(1000/(long)FPS); 
       } catch (InterruptedException ie) { 
        break; 
       } 
      } 
      recorder.stop(); 
      recorder.release(); 
      webcam.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    }; 

    b1.setOnAction(e->{ 
     Thread t = new Thread(r); 
     t.start(); 
     b2.setOnAction(e2->t.interrupt()); 
    }); 

    primaryStage.show(); 
} 

public static void main(String[] args) throws Exception { 
    launch(args); 
} 

} 
+0

Как я могу захватить только видео, я я просто хочу сохранить на своем жестком диске видео. –

+0

@JoseRamon Используйте только часть обработки видео. См. редактирование. – whitesite

+0

Я пробовал код. Когда у меня есть код внутри потока, он не работает на все. Если я просто использую код без потока, который моя камера открывается только для рамки, а затем закрывается без сохранения видео. –

Смежные вопросы