Go to file Use this template
JianGuo 7a9862eda2 refactor(webcam-capture-driver-native): 优化代码结构并调整依赖版本
- 重构部分代码,提高可读性和性能
-将 Java 版本从 11 降至 8,以支持更广泛的环境
- 移除 javafx-graphics 依赖,减少项目体积
- 更新 pom.xml 中的版本号至 1.2.0-8
2025-02-08 14:35:23 +08:00
.github/workflows Github build with macos15 2024-11-25 22:14:26 +01:00
src/main refactor(webcam-capture-driver-native): 优化代码结构并调整依赖版本 2025-02-08 14:35:23 +08:00
.gitignore Initial commit for release 2021-06-17 10:38:26 +02:00
README.md Update readme 2025-01-04 13:07:38 +01:00
maven-version-rules.xml Update dependencies 2022-12-05 10:45:56 +01:00
pom.xml refactor(webcam-capture-driver-native): 优化代码结构并调整依赖版本 2025-02-08 14:35:23 +08:00

README.md

Introduction

This is a native driver for Webcam Capture that is reliable, has very good performance, fast startup time and is able to correctly list the detailed capabilities of video devices such as resolutions and device IDs.

Currently it works on Windows, Linux and MacOS.

For Windows and Linux, it uses the NokhwaDriver, based on nokhwa through a simple and small C binding, which uses the MediaFoundation Windows API and V4L2 in Linux. For MacOS, it uses AVFDriver, based on a custom library that uses AVFoundation. When Nokhwa is stable in MacOS, this library will be updated to use NokhwaDriver for every OS.

How to use

  1. Add io.github.eduramiba:webcam-capture-driver-native:1.2.0 dependency to your application.
  2. Use the driver with Webcam.setDriver(new NativeDriver())
  3. List the devices with Webcam.getWebcams() as normal and use the library in your preferred way. In JavaFX it's recommended to do it as in the example below.

Simple example with JavaFX

import com.github.eduramiba.webcamcapture.drivers.NativeDriver;
import com.github.eduramiba.webcamcapture.drivers.WebcamDeviceWithBufferOperations;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamDevice;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestDriver extends Application {

    private static final Logger LOG = LoggerFactory.getLogger(TestDriver.class);

    public static final ScheduledExecutorService EXECUTOR = Executors.newScheduledThreadPool(4);

    public static void main(String[] args) {
        Webcam.setDriver(new NativeDriver());

        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        final ImageView imageView = new ImageView();
        final HBox root = new HBox();
        root.getChildren().add(imageView);

        Webcam.getWebcams().stream()
                .findFirst()
                .ifPresent((final Webcam camera) -> {
                    final WebcamDevice device = camera.getDevice();
                    LOG.info("Found camera: {}, device = {}", camera, device);

                    final int width = device.getResolution().width;
                    final int height = device.getResolution().height;
                    final WritableImage fxImage = new WritableImage(width, height);
                    Platform.runLater(() -> {
                        imageView.setImage(fxImage);
                        stage.setWidth(width);
                        stage.setHeight(height);
                        stage.centerOnScreen();
                    });

                    camera.getLock().disable();
                    camera.open();
                    if (device instanceof WebcamDeviceWithBufferOperations) {
                        final WebcamDeviceWithBufferOperations dev = ((WebcamDeviceWithBufferOperations) device);
                        EXECUTOR.scheduleAtFixedRate(new Runnable() {
                            private long lastFrameTimestamp = -1;

                            @Override
                            public void run() {
                                if (dev.updateFXIMage(fxImage, lastFrameTimestamp)) {
                                    lastFrameTimestamp = dev.getLastFrameTimestamp();
                                }

                            }
                        }, 0, 16, TimeUnit.MILLISECONDS);
                    }
                });

        stage.setOnCloseRequest(t -> {
            Platform.exit();
            System.exit(0);
        });

        // Create the Scene
        final Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Webcam example");
        stage.show();
    }
}

Notes

The native dynamic libraries for Mac are on src/main/resources and loaded by JNA from inside the JAR. Note that if you want to distribute a Mac app you will need to properly codesign the dylib files with entitlements, have an Info.plist, notarization...