You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

求助:Armbian Ubuntu下无法捕获带快照键USB摄像头的按键事件

解决USB摄像头快照按键无法捕获事件的思路

针对你在Armbian Ubuntu 16.04.3上遇到的问题——已经识别到摄像头快照按键对应的/dev/input/event2设备,但python-usb和python-evdev都抓不到按键事件,我整理了几个逐步排查的方向:

1. 先搞定设备权限问题

/dev/input/event*这类设备默认只有root用户有读写权限,普通用户运行Python脚本大概率会因为权限不足读不到事件。你可以先做两个验证:

  • 直接用sudo运行你的Python测试脚本,看能不能捕获按键事件;
  • 如果sudo能行,那可以给设备加持久化权限:创建udev规则文件/etc/udev/rules.d/99-camera-button.rules,内容写:
    SUBSYSTEM=="input", ATTRS{name}=="UVC Camera (eb1a:2580)", MODE="0666"
    
    然后执行sudo udevadm control --reload-rules && sudo udevadm trigger,之后普通用户就能访问这个设备了。

2. 用底层工具验证事件是否真的产生

先抛开Python,用系统自带的工具确认按键按下时有没有事件输出:

  • 安装evtest工具:sudo apt-get install evtest
  • 运行sudo evtest /dev/input/event2,然后按摄像头的快照键,看终端有没有打印出事件信息。
    • 如果evtest能看到事件,说明问题出在Python库的使用上;
    • 如果evtest也看不到,那问题根源在硬件、驱动或者系统识别环节,得往下排查。

3. 检查python-evdev的代码是否正确

如果evtest能捕获事件,那大概率是你的python-evdev代码有问题,给你一个最基础的测试代码参考:

from evdev import InputDevice, categorize, ecodes

# 打开目标输入设备
dev = InputDevice('/dev/input/event2')
print(f"监听设备: {dev.name}")

# 循环读取事件
for event in dev.read_loop():
    # 只关注按键事件
    if event.type == ecodes.EV_KEY:
        key_event = categorize(event)
        # 打印按键状态(按下/释放)和对应的键值
        print(f"按键状态: {key_event.keystate}, 键值: {key_event.keycode}")

注意:从你的设备信息里看到KEY=100000,这个对应的是KEY_SNAPSHOT,你也可以在代码里直接判断if event.code == ecodes.KEY_SNAPSHOT来精准捕获这个按键。

4. 调整python-usb的使用方向

python-usb和python-evdev的定位不同:evdev是通过系统的input子系统读取事件,而usb库是直接和USB硬件端点通信。如果你的摄像头快照按键不是通过input子系统上报事件,而是通过UVC的中断端点发送数据,那你需要换个思路:

  • 先查看摄像头的USB端点信息:lsusb -v -d eb1a:2580,找带IN方向的中断端点(比如bEndpointAddress 0x81这种格式);
  • 用python-usb连接到这个端点,循环读取数据。示例代码大概是这样:
import usb.core
import usb.util

# 找到摄像头设备
dev = usb.core.find(idVendor=0xeb1a, idProduct=0x2580)
if dev is None:
    raise ValueError('设备未找到')

# 配置设备(如果需要的话)
dev.set_configuration()

# 获取中断端点(这里假设端点地址是0x81,根据lsusb结果修改)
endpoint = dev[0][(0,0)][0]

# 循环读取端点数据
try:
    while True:
        data = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize)
        print(f"读取到数据: {data}")
except usb.core.USBError as e:
    if e.args == ('Operation timed out',):
        continue

5. 排查系统驱动与UVC兼容性

如果evtest也看不到事件,那可能是系统驱动的问题:

  • 查看dmesg日志里的UVC相关信息:dmesg | grep -i uvc,看有没有摄像头初始化失败、不支持按键功能的警告;
  • 尝试升级内核(Ubuntu 16.04可以通过sudo apt-get install linux-generic-hwe-16.04安装HWE内核,获得更好的硬件支持);
  • 有些摄像头的按键需要UVC扩展单元支持,你可以安装uvcdynctrl工具:sudo apt-get install uvcdynctrl,然后运行uvcdynctrl -l查看有没有相关的控制项,尝试启用对应的功能。

内容的提问来源于stack exchange,提问作者Wei Wang

火山引擎 最新活动