Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Cannot read properties of undefined (reading 'descriptor') #23

Open
wookayin opened this issue Jan 6, 2022 · 7 comments
Open

Comments

@wookayin
Copy link

wookayin commented Jan 6, 2022

Version:

❯❯❯ uvcc --version         
v5.0.2
❯❯❯ node --version
v17.3.0

(Note: M1 mac, arm64)

Error:

$ uvcc controls

WrappedError: Could create uvc-control object: {} ("TypeError: Cannot read properties of undefined (reading 'descriptor')")
    at CameraFactory.createWrappedError (file:///opt/homebrew/lib/node_modules/uvcc/dist/camera-factory.js:90:30)
    at CameraFactory.get (file:///opt/homebrew/lib/node_modules/uvcc/dist/camera-factory.js:74:43)
    at CommandManager.execute (file:///opt/homebrew/lib/node_modules/uvcc/dist/command-manager.js:73:47)
    at async mainAsync (file:///opt/homebrew/lib/node_modules/uvcc/dist/index.js:73:9) {
  innerError: TypeError: Cannot read properties of undefined (reading 'descriptor')
      at getInterfaceDescriptors (/opt/homebrew/lib/node_modules/uvcc/node_modules/uvc-control/index.js:375:26)
      at UVCControl.init (/opt/homebrew/lib/node_modules/uvcc/node_modules/uvc-control/index.js:85:25)
      at new UVCControl (/opt/homebrew/lib/node_modules/uvcc/node_modules/uvc-control/index.js:22:10)
      at CameraFactory.get (file:///opt/homebrew/lib/node_modules/uvcc/dist/camera-factory.js:54:28)
      at CommandManager.execute (file:///opt/homebrew/lib/node_modules/uvcc/dist/command-manager.js:73:47)
      at async mainAsync (file:///opt/homebrew/lib/node_modules/uvcc/dist/index.js:73:9)
@wookayin
Copy link
Author

wookayin commented Jan 7, 2022

This is because in uvc-control/index.js

362 function getInterfaceDescriptors(device) {
363   // find the VC interface                                   
364   // VC Interface Descriptor is a concatenation of all the descriptors that are used to fully describe
365   // the video function, i.e., all Unit Descriptors (UDs) and Terminal Descriptors (TDs)              
366   const vcInterface = device.interfaces.filter(interface => {                                         
367   ┊ const {                                                                                           
368   ┊ ┊ descriptor                                                                                      
369   ┊ } = interface                                                                                     
370   ┊ return descriptor.bInterfaceClass === CC.VIDEO &&                                                 
371   ┊ ┊ descriptor.bInterfaceSubClass === SC.VIDEOCONTROL              
372   })[0]                                                              

vcInterface is null (there is no such interface whose class is VIDEO). Why, even though there is a valid USB camera connected?

@joelpurra
Copy link
Owner

@wookayin: haven't seen that error before, and can't reproduce it. As I can't reproduce the issue (be it because of system configuration, hardware configuration, or something else) I suggest that you debug locally.

  • Is it a new/different camera model, or did it work with uvcc before?
  • Can you confirm that the expected video interfaces actually exist?
    • On Linux you can try lsusb --verbose -d 046d:082d for your device's vendor/product ids.
    • Chromium/Google Chrome has chrome://usb-internals/.
  • Can you check if the camera has multiple USB configuration descriptors, such that the exposed interfaces differs when you switch interface?

One improvement would be to check for a null vcInterface and throw a nicer error, but it's not going to fix the problem. If you find that switching the USB configuration helps, that can be part of the error message.

@wookayin
Copy link
Author

wookayin commented Jan 14, 2022

Hello @joelpurra, thanks for your reply.

I have exactly the same configuration as where it worked previously, before v5.0.2 release (though it was buggy, #22). I use Logitech BRIO 4K and 930e.

I do see the webcam device in chrome://usb-internals/ --- while doing this troubleshoothing, I can use the webcam in other programs without any issues.

The webcam device (vendor 0x046D, product 0x0891) has three interfaces:

  • Interface 0: Class Code = 14 (Video) / Subclass Code: 1
  • Interface 1: Class Code = 14 (Video) / Subclass Code: 2
  • Interface 2: Class Code = 1 (Audio) / Subclass Code = 2

The configuration descriptor looks as follows (which I cannot easily understand):

image

I also tried to print out all the vendorId, productId, interface class code for all the interfaces when searching for vcInterface, but I do get the same vendorId and productId for all the devices. The device.deviceDescriptor are always the same javascript Object (which doesn't seem right). This could also be a potentially related bug (which happens in a configuration that works fine)?

  const vcInterface = device.interfaces.filter(interface => {
    const {
      descriptor, device
    } = interface
+   console.log(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct, descriptor.bInterfaceClass);
    return descriptor.bInterfaceClass === CC.VIDEO &&
      descriptor.bInterfaceSubClass === SC.VIDEOCONTROL
  })[0]

@joelpurra
Copy link
Owner

joelpurra commented Jan 14, 2022

@wookayin: the interfaces you see, for one of your cameras, look correct. This is the interface node-uvc-control is looking for:

Interface 1: Class Code = 14 (Video) / Subclass Code: 1

You also have at least one more camera connected though.

  • Check if the correct cameras are listed by uvcc devices.
  • Please double-check that you are passing the correct vendor/product ids with uvcc --verbose when targeting a specific camera.
  • Disconnect all but one camera, and try again.
  • Reboot and try again.

There are bugs in your debugging code.

  • In your debugging, you are replacing the outer device variable with a scoped device variable inside the filtering function. This doesn't make sense. The device is picked before, and passed as an argument to the getInterfaceDescriptors function, hence it is always the same.
  • Did the printed device descriptor object have the ids of one of your two cameras, or something else?
  • Inside this filtering function, it is suggested to instead focus on debugging the the interface and the interface's descriptor.

You say that this setup worked well before, and that the only thing that differs is the uvcc versions. Then the easiest is of course to rollback to the older version.

If you want to dig deeper, here are some debugging suggestions.

  • Reinstall uvcc to remove the custom debugging code.
  • Reboot and try running uvcc once again.
  • Install an older versions of uvcc (both minor and major version changes) and see if any of them works.
  • Try Node.js v16. Remember to reinstall uvcc when switching Node.js version.

Does any combination of that work?

Note that the biggest changes to uvcc the past months have been due to breaking changes and bugs in node-usb. You are already looking at code from node-uvc-control, but please keep in mind that they are from the forked version specifically for uvcc. There are many more stylistic issued and bugs in node-uvc-control that I don't want to spend time fixing. Only minimum effort at this time.

@eparadis
Copy link

I've read this thread and I'm not sure I'll be able to contribute much, but I'd like to report I also see this bug.

$ uvcc --version
v5.0.2
$ node --version
v17.0.1

This is on an Intel Mac Mini (2018). The camera I have attached is a Logitech C615.

$ sudo uvcc devices
[
  {
    "name": "HD Webcam C615",
    "vendor": 1133,
    "product": 2092,
    "address": 30
  }
]
# note: it hangs here. I must use CTRL-C to exit

Error using uvcc controls:

$ uvcc controls
WrappedError: Could create uvc-control object: {} ("TypeError: Cannot read properties of undefined (reading 'descriptor')")
    at CameraFactory.createWrappedError (file:///usr/local/lib/node_modules/uvcc/dist/camera-factory.js:90:30)
    at CameraFactory.get (file:///usr/local/lib/node_modules/uvcc/dist/camera-factory.js:74:43)
    at CommandManager.execute (file:///usr/local/lib/node_modules/uvcc/dist/command-manager.js:73:47)
    at async mainAsync (file:///usr/local/lib/node_modules/uvcc/dist/index.js:73:9) {
  innerError: TypeError: Cannot read properties of undefined (reading 'descriptor')
      at getInterfaceDescriptors (/usr/local/lib/node_modules/uvcc/node_modules/uvc-control/index.js:375:26)
      at UVCControl.init (/usr/local/lib/node_modules/uvcc/node_modules/uvc-control/index.js:85:25)
      at new UVCControl (/usr/local/lib/node_modules/uvcc/node_modules/uvc-control/index.js:22:10)
      at CameraFactory.get (file:///usr/local/lib/node_modules/uvcc/dist/camera-factory.js:54:28)
      at CommandManager.execute (file:///usr/local/lib/node_modules/uvcc/dist/command-manager.js:73:47)
      at async mainAsync (file:///usr/local/lib/node_modules/uvcc/dist/index.js:73:9)

Perhaps this data point will help someone else.

@joelpurra
Copy link
Owner

@wookayin, @eparadis: which version of macOS are you using? Have seen reports of issues with macOS 12 in other projects.

The current approach where the USB device is accessed directly, implemented by for example node-uvc-control and libuvc, might not work anymore. Windows has similar problems, but not for merely adjusting UVC controls. It seems Apple changed how USB webcams are accessed; perhaps there are system configuration workarounds. Am, as mentioned, not using macOS 12 (neither Intel nor ARM version) myself so am not able to work on this issue.

@mcuee
Copy link

mcuee commented Sep 5, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants