本文为《PVE安装Kodi》系列文章的一部分。
本文同步发表在我的个人博客https://devome.github.io/blog。
- PVE 直接安装最新版 Kodi
- 为Kodi适配遥控器
- 修改Kodi字幕字体
- 修改Kodi皮肤字体
- 屏蔽Kodi的关机、重启按钮
- 设置Kodi启动的前置条件
- 像使用盒子/LibreELEC一样使用PVE直装的Kodi,实现遥控器启停
- kodi-send使用相关说明
- 转换遥控器的esc键为backspace键
前言
在《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
的设备。设备的编号会随着外设的插入或卸载以及开关机的变化而变化,也就是说电源键所在的输入设备的eventX
中X
这个编号不是固定的,所以我们不能直接使用/dev/input/eventX
来作为后续要胁持的输入设备。运行ls -l /dev/input/by-id
,udev
会在这个目录下创建易于识别的、唯一的、不随外设的插入卸载或开关机而变化的软连接,无论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 Control
和2.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环境中创建后再上传。
-
下载我为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
-
按照《PVE 直接安装最新版 Kodi》安装好Kodi,建议按非root用户设置好
/etc/systemd/system/kodi.service
,注意含有ExecStart
和ExecStop
这两行。如果你不需要Kodi开机自动启动,那么创建好这个文件就好了,不需要运行systemctl enable --now kodi.service
。 -
新建一个用来自动判断是启动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
。 -
根据 evsieve 的说明,在运行
evsieve
时,它所要胁持的设备必须已经插入了,但是我又希望evsieve
能够开机自动运行,所以我需要在正式运行前先确保2.4G Composite Devic System Control
这个设备已经插入。这项工作就交给脚本来判断吧,新建/usr/local/bin/evsieve.sh
,内容如下(注意按照注释修改target_hijack_input_device
和target_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
。 -
新建
/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
-
让
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.
-
有些遥控器的返回键不是真正的返回键,而是退出键,会直接退出到主菜单,而不是返回到上一层。如果不习惯这样的操作方式,那么我们可以仍然借助evsieve这个工具来实现按键的转换。详见 转换遥控器的退出键为返回键。
总结
通过本教程,PVE直接安装Kodi也变得很好用了,就像使用电视盒子/LibreELEC/CoreELEC一样,实现遥控器启动/停止。
网友评论