使用Java中的网络摄像头捕获video

我试图从java应用程序捕获video截图。 我已经下载了sarxos / webcam-capture库。 我已将可执行jar添加到我的项目中。 这有点乱。 我想从我创建的简单javafx接口捕获video。 问题是在安装了lib和slf4后,它还需要安装xuggle。 我在路径中添加了xuggle,我的代码如下:

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库。 我在我的项目中添加了所有必需的库我运行以下代码: 在这里输入链接描述 ,代码工作正常我设法存储video,但最后我收到以下错误:

8614 [JNIWrapper.ShutdownHook]错误com.jniwrapper.NativeResourceCollector – com.jniwrapper.FunctionExecutionException:com.jniwrapper.Function.invokeVirtualFunc(本机方法)中的回调参数类型或其计数不正确

知道这个错误是什么意思吗? 什么是JNIWrapper.ShutdownHook? 我尝试了3台不同的机器中的代码,这只发生在其中一台机器上? 我该如何处理这个exception?

编辑3:我试过@whitesite提案EDIT3。 gui开始了,我有两个按钮启动和停止启动按钮打开相机,当我试图停止时,我收到以下内容:

java.lang.NullPointerException:参数0的指针地址为NULL。 at org.bytedeco.javacpp.opencv_videoio $ VideoWriter.write(Native Method)atg.bytedeco.javacv.OpenCVFrameRecorder.record(OpenCVFrameRecorder.java:105)at test1.lambda $ 0(Test1.java:52)at java.lang。 Thread.run(未知来源)

您在类路径中缺少slf4-api-ver.jar。 但是,只添加api是不够的,您还需要像slf4j-simple-ver.jar这样的提供程序。 最新版本为1.7.21版本,可从http://www.slf4j.org/download.html下载

好的,这就是我使用这个JavaCV库及其示例所得到的:

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

它从网络摄像头捕获video并实时翻译,同时写入文件。 您需要使用maven或手动安装以及来自二进制zip存档的所有jar来在classpath中包含它们的库。 也许你不需要所有这些,但我没有深入挖掘。
您可以使用设置并调查示例和来源。 从我所看到的它是非常强大的库。
编辑
只是video处理部分:

 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。
编辑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将这些图像记录到video文件中(就像你在问题中的exapmle,只是javaCV而不是xuggler)。 这是一个小型的javafx应用程序,它有两个按钮:'Start'启动videoProcessing线程捕获video,'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); } }