How to check which is / dev / video ?? when multiple webcams are inserted

problem

If you only want to insert one webcam, you should usually connect it to / dev / video0


$ fswebcam -d /dev/video0 a.jpg
#Or by default/dev/Because it is video0
$ fswebcam a.jpg

However, if you have two or more cameras, you will not know which camera is / dev / video0 or 2.

Solution

You can output such a list by using v4l2-ctl.

Example with raspberry Pi


$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
	/dev/video10
	/dev/video11
	/dev/video12

bcm2835-isp (platform:bcm2835-isp):
	/dev/video13
	/dev/video14
	/dev/video15
	/dev/video16

BUFFALO BSW32KM03 USB PC Camera (usb-20980000.usb-1.3):
	/dev/video0
	/dev/video1

UVC Camera (046d:0825) (usb-20980000.usb-1.5):
	/dev/video2
	/dev/video3

The point to note here is that the camera has a (usb-20980000.usb-1.5) style. And this ʻusb-1.5` part is tied to the physical USB port ([reference] 1).

So, if you keep the webcam plugged in all the time, the USB number of that camera will be fixed, so if you use the first path (/ dev / video *) written below it, the camera image ([The other is metadata?] 2).

A simple ruby script based on these

require "./video_paths"
VideoPaths.paths # => {"1.3"=>"/dev/video0", "1.5"=>"/dev/video2"}
require "memoist"
require "active_support/core_ext/object/blank"

class VideoPaths
  USB_NUMBER_REG = /\.usb\-([\d\.]+)/

  class << self
    extend Memoist
    def paths
      new.to_h
    end
    memoize :paths
  end

  def initialize
    @output = `v4l2-ctl --list-devices`
    clean_output
  end

  def to_h
    camera_names.to_h do |camera_name|
      key, valid_path, *other_paths = group_by_camera_name[camera_name]
      [extract_usb_number(camera_name), valid_path]
    end
  end

  private

  attr_reader :output

  def group_by_camera_name
    key = :not_yet
    output.group_by do |line|
      key = line if line.end_with?(":")
      key
    end
  end

  # BUFFALO BSW32KM03 USB PC Camera (usb-20980000.usb-1.3):
  #                         ^^^^^^^^
  def camera_names
    group_by_camera_name.keys.select { |key| key.match?(/camera/i) }
  end

  # BUFFALO BSW32KM03 USB PC Camera (usb-20980000.usb-1.3):
  #                                               ^^^^^^^^
  def extract_usb_number(camera_name)
    camera_name.match(USB_NUMBER_REG)[1]
  end

  def clean_output
    @output = output.lines.collect(&:strip).delete_if(&:blank?)
  end
end

Recommended Posts

How to check which is / dev / video ?? when multiple webcams are inserted
How to write a string when there are multiple lines in python
How to turn the for statement when there are multiple values for one key in the dictionary
How to check when python-memcached server could not be connected
How to improve when Spyder's editor is very heavy in Mavericks