本文为《PVE安装Kodi》系列文章的一部分。
- PVE 直接安装最新版 Kodi
- 为Kodi适配遥控器
- 修改Kodi字幕字体
- 修改Kodi皮肤字体
- 屏蔽Kodi的关机、重启按钮
- 设置Kodi启动的前置条件
- 像使用盒子/LibreELEC一样使用PVE直装的Kodi,实现遥控器启停
- kodi-send使用相关说明
- 转换遥控器的退出键为返回键
前言
在《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
程序先找出遥控器电源键在什么设备上。
|
|
通过测试,我知道了我遥控器的电源键的键码为116
,键名为KEY_POWER
,去掉KEY_
,键值转换为小写power
这个值在后面会用到。不出意外,一般遥控器的电源键的键值都是power
。
现在来找一下event8
这个设备在/dev/input/by-id
下的软连接叫什么,运行ls -l /dev/input/by-id/
:
|
|
这……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 --attribute-walk --name=/dev/input/eventX
(X更换为不同的设备编号)可知,我的设备2.4G Composite Devic System Control
可以通过ATTRS{name}
这个属性即可以进行唯一识别。参考 udev 这个链接,新建/etc/udev/rules.d/01-system-control.rules
,内容如下:
|
|
这种方式是写死的,只针对这一个遥控器有效,复杂的规则咱也写不来…当然如果你想采用更智能的识别方式,可以参考 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
这个设备。软连接名称你可以自行定义。
现在重启下或者重插一下接收器,终于可以识别出来了:
|
|
设置按键胁持
以下相关命令均为root用户执行的。
如果需要新建文件,请直接在Linux环境中使用
nano XXXX
创建,请不要在Windows环境中创建后再上传。
-
下载我为PVE 7.X预编译好的 evsieve,其他版本不保证可用,如果下载不了,可以按照官方教程自己编译。我会随着Debian和evsieve版本的升级一直更新该文件,请及时在这个仓库查看更新情况:devome/files@github
1 2 3 4 5
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
来使用,内容如下:1 2 3 4 5 6 7 8 9
#!/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
):1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#!/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
。注意:如果在进行
evtest
时,电源键所在的设备组在Event type 1
下支持的Event code
不仅仅只有KEY_POWER
KEY_SLEEP
KEY_WAKEUP
这三个,那么一般情况下这个设备组还有其他按键,这时不能完全屏蔽掉整个设备,需要将上述脚本中最后四行改成下面这样。这种情况一般出现在蓝牙遥控器上面。1 2 3 4 5
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 \ --output
-
新建
/etc/systemd/system/evsieve.service
,内容如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[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关机。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
## 设置开机自动启动,并立即运行起来 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一样,实现遥控器启动/停止。