sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.28k stars 1.11k forks source link

selecting drivers when using Webcam wc = new Webcam #630

Open orouly opened 6 years ago

orouly commented 6 years ago

I would like to be able to specify that my 2-cam system use USB 2.0 as the system driver. I would prefer not to use the General UVC & USB 2.0, one-for-each camera, that comes up as the default.

QUESTION; 1) Is it possible to invoke the USB 2.0 driver n-times?, 2) Is there example code demonstrating how to invoke a particular driver?, and 3) How do I get the system name of the driver I want to invoke? DETAIL: I am coded using the basic Webcam wc = new Webcam () pattern. (Example follows.)

Your code is stable and has made my project possible. Thank you.

Maelzel

EXAMPLE: int item = 0; for ( Webcam webcam : Webcam.getWebcams () ) { webcam.setViewSize ( WebcamResolution.VGA.getSize () ); if ( item == 0 ) cameraRight = webcam; if ( item == 1 ) cameraLeft = webcam; item++; }

sarxos commented 6 years ago

Hi @orouly,

I do not understand to what kind of drivers you are referring to as USB 2.0 driver and General UVC driver. In Webcam Capture API you only have abstraction, something called capture driver, which is not the same as the low-level USB/UVC drivers used by the operating system. Webcam Capture API has nothing to do with USB in general, and there is no code to differentiate USB/UVC. Webcam Capture API utilizes the idea of capture frameworks. The capture framework abstracts API installed or pre-installed in operating system (e.g. DirectShow, GStreamer, V4L, etc), or HTTP client in case of IP cameras, which is used to access webcam devices which are exposed by these frameworks. The exposure of native webcam devices through capture framework is different in each case, and the goal of Webcam Capture project is to provide simple and unified API, so users does not have to deal with different implementations when integrating webcam in their applications. Instead, when you would like to migrate from one capture framework to the other (e.g. from DirectShow to GStreamer or OpenCV) you can simply switch the capture driver used by the project without rewriting your code.

orouly commented 6 years ago

Yes, thank you. That's what I thought. Best regards, and thanks again for the library.

sarxos commented 6 years ago

Hi again @orouly,

From your code example I suppose that you would like to select webcam by name? Is this correct? In this case this is what you should do:

  1. Iterate over all available webcams and save their names:
for (Webcam webcam : Webcam.getWebcams()) {
    System.out.println(webcam.getName());
}

This will output something like (names format differs between operating systems, this one is from Linux).

Integrated Camera /dev/video0
HD Webcam /dev/video1

These names will most likely be different in your case, but now you can use these names to access specific webcam without doing for/each loop. The names will not change if you keep the webcams on the same USB ports as they were connected when you listed them.

  1. Select webcam by names:
Webcam cameraLeft = Webcam.getWebcamByName("Integrated Camera /dev/video0");
Webcam cameraRight = Webcam.getWebcamByName("HD Webcam /dev/video1");

Please let me know if you have any further questions.

orouly commented 6 years ago

Yes, Sarxos. That's exactly what I wanted to do. And, I did that yesterday. But, I ran into trouble.

You see, I want to use my 'USB 2.0 Device # in my system twice. Instead, my Win 7/10 platforms both INSIST on making me use 'GENERAL UVC' for one cam and 'USB 2.0 Device' for the other. However, my webcams are identical - supposedly, same manufacturer. And, moreover, I have four cameras to work with overall.

Device instance path: USB\VID_1902&PID_3232\6&23D3AEF0&0&4 for one. Device instance path: USB\VID_1908&PID_3231\20110616000000 for the other.

When I use my Logitech 9000 cams, the Logitech driver loads twice. That is, it does not make me use the Logitech driver for one cam and some other driver for another. These Logitech cams are a separate pair - beyond the four I mentioned above.

I tried UNINSTALLING the drivers completely: that did not help. I tried to edit the Windows registry: that did not help as the registry entry was in a write-protected mode and I was refused.

Your code works great!!! The problem is my 'preferred' webcams seem to work OK with the USB 2.0 driver and to work poorly with the GENERAL UVC cam. I find this confusing since I suspect the same code is being reused by the OS but just given a different symbolic name. I figured if I could FORCE the system to iterate the symbolic name USB 2.0 DEVICE 0/1 using your code I might overcome the issue somehow.

Using your example I'd like to accomplish: Webcam cameraLeft = Webcam.getWebcamByName("HD Webcam /dev/video 0"); Webcam cameraRight = Webcam.getWebcamByName("HD Webcam /dev/video 1");

I apologize if I sound 'duff.' That's what I'm trying to do.

orouly

orouly commented 6 years ago

Sarxos, In that last post I answered my own question: I suspected a HW issue... 3 or my 4 cams were using the PID3232 instance. So, I ran a test with 2 of those 3 and found the following per your suggestion.

orouly commented 6 years ago

Sarxos, In that last post I answered my own question: I suspected a HW issue... 3 or my 4 cams were using the PID3232 instance. So, I ran a test with 2 of those 3 and found the following per your suggestion.

[main] INFO com.github.sarxos.webcam.Webcam - WebcamDefaultDriver capture driver will be used CAM NAME BASE: GENERAL - UVC 0 CAM NAME 0: GENERAL - UVC 0 [atomic-processor-1] INFO com.github.sarxos.webcam.ds.cgt.WebcamOpenTask - Opening webcam GENERAL - UVC 0

INFO: Right camera found. Preparing camera. Done. INFO: Camera ready.

CAM NAME BASE: GENERAL - UVC 1 CAM NAME 1: GENERAL - UVC 1 [atomic-processor-1] INFO com.github.sarxos.webcam.ds.cgt.WebcamOpenTask - Opening webcam GENERAL - UVC 1

INFO: Left camera found. Preparing camera. Done. INFO: Camera ready.

Apparently, the iteration scheme I wanted was available all along. I had avoided it because the cams that use the GENERAL UVC driver produce undesirable side-effects in their images. However, by forcing the question and using 2 of the "poorly performing cams" I discovered the desired iteration.

Thank you for your time, patience, and above all your code.

Cheers