像使用盒子/LibreELEC一样使用PVE直装的Kodi,实现遥控器启停

本文为《PVE安装Kodi》系列文章的一部分。

本文同步发表在我的个人博客https://evine.win

前言

在《PVE 直接安装最新版 Kodi》一文的评论中,有网友提出能不能像操控电视盒子/LibreELEC/CoreELCE一样用遥控器操控PVE中直装的Kodi,实现打开和关闭Kodi,这是个好想法,我也认为这样会大方便PVE中直装的Kodi的使用,所以学习了相关udev、udevadm、evtest、input、input remap相关知识,终于实现了这个非常便于使用的功能。

参考资料

udev, udevadm, evtest, input_remap_utilities, evsieve

思路

用遥控器操控PVE中直装的Kodi,实现打开和关闭Kodi,这个场景需要在无桌面环境下,胁持遥控器的电源键,让它的作用变更为打开/关闭Kodi,所以只是将电源键映射为其他键是不行的,而是需要胁持遥控器的电源键,让它变更为运行某个脚本,然后由脚本实现打开/关闭Kodi。

根据 input_remap_utilities 列出的几个按键映射工具,只有 evsieve 可以在无桌面环境下胁持按键并运行指定脚本,实现上述场景。

准备工作

以下相关命令均为root用户执行的。

如果需要新建文件,请直接在Linux环境中使用nano XXXX创建,请不要在Windows环境中创建后再上传。

所有的输入设备都由udev程序识别并保存在/dev/input下,通过输入ls -l /dev/input可以查看到许多eventX的设备。设备的编号会随着外设的插入或卸载以及开关机的变化而变化,也就是说电源键所在的输入设备的eventXX这个编号不是固定的,所以我们不能直接使用/dev/input/eventX来作为后续要胁持的输入设备。运行ls -l /dev/input/by-idudev会在这个目录下创建易于识别的、唯一的、不随外设的插入卸载或开关机而变化的软连接,无论X如何变化,它们都将指向正确的设备。

我的遥控器是自带接收器的2.4G无线遥控器,插上接收器,通过evtest程序先找出遥控器电源键在什么设备上。

# 安装evtest
apt install evtest

# 运行evtest
evtest --grab

# evtest会列出所有可用的输入设备,可以看到我的遥控器有event5-event8共4个设备
# 你可以选择具体的编号来进行测试,找到每个设备分别能控制哪些按键
# 经过测试,我发现我遥控器的电源键在event8,也就是2.4G Composite Devic System Control这个设备
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      Power Button
/dev/input/event1:      AT Translated Set 2 keyboard
/dev/input/event2:      VirtualPS/2 VMware VMMouse
/dev/input/event3:      VirtualPS/2 VMware VMMouse
/dev/input/event4:      QEMU QEMU USB Tablet
/dev/input/event5:      2.4G Composite Devic
/dev/input/event6:      2.4G Composite Devic Mouse
/dev/input/event7:      2.4G Composite Devic Consumer Control
/dev/input/event8:      2.4G Composite Devic System Control
/dev/input/event9:      PC Speaker
Select the device event number [0-9]:8   # 手动输入要测试的设备编号,如果不清楚电源键在什么设备上,你可以一个一个试出来
Input device ID: bus 0x3 vendor 0x627 product 0x697d version 0x110
Input device name: "2.4G Composite Devic System Control"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 116 (KEY_POWER)
    Event code 142 (KEY_SLEEP)
    Event code 143 (KEY_WAKEUP)
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)
Properties:
Testing ... (interrupt to exit)  # 按下电源键,evtest输出以下结果,没有反应表示设备择取不对
Event: time 1669209045.421999, type 4 (EV_MSC), code 4 (MSC_SCAN), value 10081
Event: time 1669209045.421999, type 1 (EV_KEY), code 116 (KEY_POWER), value 1
Event: time 1669209045.421999, -------------- SYN_REPORT ------------
Event: time 1669209045.422021, type 1 (EV_KEY), code 116 (KEY_POWER), value 0
Event: time 1669209045.422021, -------------- SYN_REPORT ------------

# Ctrl+C退出

通过测试,我知道了我遥控器的电源键的键码为116,键名为KEY_POWER,去掉KEY_,键值转换为小写power这个值在后面会用到。不出意外,一般遥控器的电源键的键值都是power

现在来找一下event8这个设备在/dev/input/by-id下的软连接叫什么,运行ls -l /dev/input/by-id/

total 0
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-event-if01 -> ../event7
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-event-kbd -> ../event5
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-if01-event-mouse -> ../event6
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-if01-mouse -> ../mouse3
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-QEMU_QEMU_USB_Tablet_28754-0000:00:01.2-1-event-mouse -> ../event4
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-QEMU_QEMU_USB_Tablet_28754-0000:00:01.2-1-mouse -> ../mouse2

这......udev没有识别出来......准确的讲,是因为udev的默认规则/usr/lib/udev/rules.d/60-persistent-input.rules无法区分2.4G Composite Devic Consumer Control2.4G Composite Devic System Control这两个设备,现象是每次关机再开机或每次卸载再插入接收器后,usb-0627_2.4G_Composite_Devic-event-if01这个设备一会儿指向2.4G Composite Devic Consumer Control,一会儿指向2.4G Composite Devic System Control,所以我需要修改一下udev的规则,让它能够准确识别出2.4G Composite Devic System Control。可能其他遥控器不存在此问题,需要你自行测试一下此问题存在不存在。

现在来让udev能准确识别2.4G Composite Devic System Control,运行udevadm info --attribute-walk --name=/dev/input/event8(其中event8是根据上面evtest测试后知道的),输出内容:

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

looking at device '/devices/pci0000:00/0000:00:1e.0/0000:01:1b.0/usb2/2-1/2-1:1.1/0003:0627:697D.0003/input/input9/event8':
    KERNEL=="event8"
    SUBSYSTEM=="input"
    DRIVER==""
    ATTR{power/async}=="disabled"
    ATTR{power/control}=="auto"
    ATTR{power/runtime_active_kids}=="0"
    ATTR{power/runtime_active_time}=="0"
    ATTR{power/runtime_enabled}=="disabled"
    ATTR{power/runtime_status}=="unsupported"
    ATTR{power/runtime_suspended_time}=="0"
    ATTR{power/runtime_usage}=="0"

looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:01:1b.0/usb2/2-1/2-1:1.1/0003:0627:697D.0003/input/input9':
    KERNELS=="input9"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{capabilities/abs}=="0"
    ATTRS{capabilities/ev}=="13"
    ATTRS{capabilities/ff}=="0"
    ATTRS{capabilities/key}=="c000 10000000000000 0"
    ATTRS{capabilities/led}=="0"
    ATTRS{capabilities/msc}=="10"
    ATTRS{capabilities/rel}=="0"
    ATTRS{capabilities/snd}=="0"
    ATTRS{capabilities/sw}=="0"
    ATTRS{id/bustype}=="0003"
    ATTRS{id/product}=="697d"
    ATTRS{id/vendor}=="0627"
    ATTRS{id/version}=="0110"
    ATTRS{inhibited}=="0"
    ATTRS{name}=="2.4G Composite Devic System Control"
    ATTRS{phys}=="usb-0000:01:1b.0-1/input1"
    ATTRS{power/async}=="disabled"
    ATTRS{power/control}=="auto"
    ATTRS{power/runtime_active_kids}=="0"
    ATTRS{power/runtime_active_time}=="0"
    ATTRS{power/runtime_enabled}=="disabled"
    ATTRS{power/runtime_status}=="unsupported"
    ATTRS{power/runtime_suspended_time}=="0"
    ATTRS{power/runtime_usage}=="0"
    ATTRS{properties}=="0"
    ATTRS{uniq}==""

...下面其他信息此处略去

通过多次运行udevadm info --attribute-walk --name=/dev/input/eventX(X更换为不同的设备编号)可知,我的设备2.4G Composite Devic System Control可以通过ATTRS{name}这个属性即可以进行唯一识别。参考 udev 这个链接,新建/etc/udev/rules.d/01-system-control.rules,内容如下:

ATTRS{name}=="2.4G Composite Devic System Control", SYMLINK+="input/by-id/usb-0627_2.4G_Composite_Devic-System-Control"

这种方式是写死的,只针对这一个遥控器有效,复杂的规则咱也写不来...当然如果你想采用更智能的识别方式,可以参考 Writing udev rules编写udev规则

其中SYMLINK+="input/by-id/usb-0627_2.4G_Composite_Devic-System-Control"是指让udev/dev/input/by-id下自动创建usb-0627_2.4G_Composite_Devic-System-Control,其指向2.4G Composite Devic System Control这个设备。软连接名称你可以自行定义。

现在重启下或者重插一下接收器,终于可以识别出来了:

ls -l /dev/input/by-id

## 生成了`usb-0627_2.4G_Composite_Devic-System-Control`这个软连接
total 0
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-event-if01 -> ../event7
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-event-kbd -> ../event5
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-System-Control -> ../event8
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-if01-event-mouse -> ../event6
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-0627_2.4G_Composite_Devic-if01-mouse -> ../mouse3
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-QEMU_QEMU_USB_Tablet_28754-0000:00:01.2-1-event-mouse -> ../event4
lrwxrwxrwx 1 root root 9 Nov 23 22:40 usb-QEMU_QEMU_USB_Tablet_28754-0000:00:01.2-1-mouse -> ../mouse2

设置按键胁持

以下相关命令均为root用户执行的。

如果需要新建文件,请直接在Linux环境中使用nano XXXX创建,请不要在Windows环境中创建后再上传。

  1. 下载我为PVE 7.X预编译好的 evsieve,其他版本不保证可用,如果下载不了,可以按照官方教程自己编译。我会随着Debian和evsieve版本的升级一直更新该文件,请及时在这个仓库查看更新情况:devome/files@github

    wget https://raw.githubusercontent.com/devome/files/master/evsieve/evsieve -O /usr/local/bin/evsieve
    chmod +x /usr/local/bin/evsieve
    
    ## 安装evsieve的运行依赖
    apt install libevdev2
    
  2. 按照《PVE 直接安装最新版 Kodi》安装好Kodi,建议按非root用户设置好/etc/systemd/system/kodi.service,注意含有ExecStartExecStop这两行。如果你不需要Kodi开机自动启动,那么创建好这个文件就好了,不需要运行systemctl enable --now kodi.service

  3. 新建一个用来自动判断是启动Kodi还是关闭Kodi的脚本/usr/local/bin/kodi-power.sh,后续由evsieve来使用,内容如下:

    #!/usr/bin/env bash
    
    export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    
    if [[ -z $(ps -ef | grep "kodi.bin" | grep -v "grep") ]]; then   ## 如果kodi还没有启动,那么就启动它
        systemctl start kodi.service
    else   ## 如果kodi已经启动了,那么就停止它
        systemctl stop kodi.service
    fi
    

    注:停止Kodi这一行,相比使用systemctl stop kodi.service,更推荐使用kodi-send,详见:kodi-send使用相关说明

    注意增加可执行权限:chmod +x /usr/local/bin/kodi-power.sh

  4. 根据 evsieve 的说明,在运行evsieve时,它所要胁持的设备必须已经插入了,但是我又希望evsieve能够开机自动运行,所以我需要在正式运行前先确保2.4G Composite Devic System Control这个设备已经插入。这项工作就交给脚本来判断吧,新建/usr/local/bin/evsieve.sh,内容如下(注意按照注释修改target_hijack_input_devicetarget_hijack_button):

    #!/usr/bin/env bash
    
    export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    
    ## 要胁持的目标设备的绝对路径,请注意修改成自己的
    ## 不要直接写/dev/input/eventX,而要写/dev/input/by-id下的设备
    target_hijack_input_device="/dev/input/by-id/usb-0627_2.4G_Composite_Devic-System-Control"
    
    ## 要胁持的按键的键名,请注意修改成你获取到的,不出意外,一般遥控器的电源键的键值都是power
    target_hijack_button="power"
    
    ###### 以下无需修改 ######
    ## 先检测 target_hijack_input_device 是否已经存在
    while :; do
        if [[ -L "$target_hijack_input_device" ]]; then
            break
        else
            echo "The '$target_hijack_input_device' is not inserted, wait 2 seconds..."
            sleep 2
        fi
    done
    
    ## 执行电源键胁持,当按下指定键时,转换为运行脚本/usr/local/bin/kodi-power.sh,详细用法请见:https://github.com/KarsMulder/evsieve
    exec evsieve \
        --input "$target_hijack_input_device" grab persist=reopen \
        --hook key:$target_hijack_button exec-shell="/usr/local/bin/kodi-power.sh" \
        --block key:$target_hijack_button
    

    该脚本同样需要可执行权限:chmod +x /usr/local/bin/evsieve.sh

  5. 新建/etc/systemd/system/evsieve.service,内容如下:

    [Unit]
    Description = Run evsieve
    Requires = systemd-udevd.service
    After = systemd-udevd.service
    Wants = systemd-udevd.service
    
    [Service]
    User = root
    Group = root
    ExecStart = /usr/local/bin/evsieve.sh
    ExecStop = /usr/bin/killall --user root --exact --wait evsieve
    TimeoutStartSec = infinity
    Restart = on-abort
    
    [Install]
    WantedBy = multi-user.target
    
  6. evsieve.service开机启动启动。这个必须得开机自动启动,要不然胁持不了。运行并确保evsieve.service已经运行好后,按一下遥控器的电源键来试一试效果吧。

    注意:因为Kodi程序比较大,无论是启动Kodi,还是关闭Kodi,系统都需要一定时间来处理,所以不要连续按电源键,这样只会让系统混乱。

    注意:如果evsieve.service没有正常启动,可能按下电源键会让PVE关机。

    ## 设置开机自动启动,并立即运行起来
    systemctl enable --now evsieve.service
    
    ## 再看看是不是evsieve.service是不是启动好了
    systemctl status evsieve.service
    
    ## 如果像这样就表示启动好啦
     evsieve.service - Run evsieve
         Loaded: loaded (/etc/systemd/system/evsieve.service; enabled; vendor preset: enabled)
         Active: active (running) since Thu 2022-11-24 18:11:27 CST; 36min ago
       Main PID: 1249 (evsieve)
          Tasks: 2 (limit: 72123)
         Memory: 1.8M
            CPU: 59ms
         CGroup: /system.slice/evsieve.service
                 └─1249 evsieve --input /dev/input/by-id/usb-0627_2.4G_Composite_Devic-System-Control grab persist=reopen --hook key:power exec-shell=/usr/local/bin/kodi-power.sh --block key:power
    11月 24 18:11:27 pve systemd[1]: Started Run evsieve.
    
  7. 有些遥控器的返回键不是真正的返回键,而是退出键,会直接退出到主菜单,而不是返回到上一层。如果不习惯这样的操作方式,那么我们可以仍然借助evsieve这个工具来实现按键的转换。详见 转换遥控器的退出键为返回键

总结

通过本教程,PVE直接安装Kodi也变得很好用了,就像使用电视盒子/LibreELEC/CoreELEC一样,实现遥控器启动/停止。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容