折腾一个网络电视(下)

/ 0评 / 0

电视,自动化。

本篇是「折腾一个」系列的第 3 篇。上一篇:《折腾一个网络电视(上)》。

在上一篇里面,我们还留了一个小尾巴没有处理。结果这个小尾巴的处理比我预先设想的要更困难一些。所以单独开一篇继续配置。

Kodi 的完全独立模式

上一篇中我们安装桌面环境其实并不是完全必要的,因为 Kodi 有一个非常神奇的能力叫「独立模式」,即不依赖任何桌面环境就能运行。当然,我们仍然需要安装图形服务(X11 或者 Wayland)和显卡驱动。

为了节省本就不多的硬盘空间(海量存储虽然也在这台机器上,但是只用于存储其他数据而不存储系统文件),我们还是切换到独立模式下运行,并删除之前安装的桌面环境。

首先,一句话安装:

# yaourt -S kodi-standalone-service

这个包会提供 kodi-x11.servicekodi-wayland.service 服务,分别用于 X11 和 Wayland 的自动部署独立模式。一般如果桌面能正常显示的话,这个服务就能正常运行。先启用(但是别启动)这个服务,然后停止显示管理器服务,之后我们就可以删除桌面和显示管理器了:

# yaourt -Rc lxde lxdm

如果之前安装过 PulseAudio, 那么也要一并卸载,否则会没有声音。

重启后,Kodi 会自动启动。

自动开关机

在阅读了几十页文档之后,我终于摸索出了自动开关机的方案。

首先,「自动」这部分很好做,只需要借助 systemd 的定时任务即可。比较麻烦的是开机和关机的动作。因为我并不需要真的关闭计算机或者让计算机进入休眠状态,所以并不能直接使用 Kodi 内建的计划任务或者定时器插件。在独立模式下运行的 Kodi 实例也无法通过提供命令行参数的方法选择需要播放的内容。

所以需要接入 Kodi 的 JSON RPC. 不过好在存在一个通过命令行调用 Kodi JSON RPC 的程序 kodi-eventclients 提供 kodi-send 命令,这样就不需要再自己写接口程序了。同时,由于 kodi-x11.service 中的配置,Kodi 运行在自己独立的 user-*.slice 中,这意味着如果我们登录控制台并关机或重启的话,Kodi 实例会被直接杀死而不是正常退出(相当于你作为系统管理员直接关机或重启了电脑)。所以一般而言,如果 Kodi 还在正常运行,应该考虑让 Kodi 进行系统的关机或重启操作。

首先是想办法让电视关机。可以用 kodi-send -a "PlayerControl(Stop)" 停止当前播放的节目,然后就等这玩意自动休眠关闭屏幕就行。可以在设置中将屏保时间设为 1 分钟。

电视可以关机后,就是再开机。开机的命令翻了很长时间,终于找到一个 kodi-send -a "Action(PlayPvrTV)" 命令可以继续播放最后一次看的频道。

但等待屏幕自动休眠总感觉不太好。能不能停止播放节目后立刻就关闭屏幕呢?

我第一个想到的方案是用 xset. 这个命令可以用于向显示器发送电源控制信号,比如要立刻关闭屏幕,可以执行 xset dpms force off. 要立刻唤醒屏幕,则可以执行 xset dpms force on.

但是好玩的事情是,如果只是单纯执行 xset dpms force off 的话,Kodi 会立刻再把屏幕唤醒。所以还是得接着研究。最终找到另一条 Kodi 的指令:kodi-send -a "ToggleDPMS". 好像没有单独的打开显示器或关闭显示器的命令,而且如果用了这个命令,之后再用 xset 启动屏幕的话,Kodi 就会黑屏,直到再通过 ToggleDPMS 把状态重新对上为止。

算了,姑且凑合着用。

将这两条命令写成脚本文件:

#!/bin/bash
# /opt/autotv/start.sh

export DISPLAY=:0

kodi-send -a "ToggleDPMS"
sleep 1
kodi-send -a "Action(PlayPvrTV)"
#!/bin/bash
# /opt/autotv/stop.sh

export DISPLAY=:0

kodi-send -a "PlayerControl(Stop)"
sleep 1
kodi-send -a "ToggleDPMS"

然后创建 /etc/systemd/system/kodi-start.service/etc/systemd/system/kodi-stop.servicesystemd 可以调用这两个脚本:

[Unit]
Description = Start Kodi
Requires = kodi-x11.service
After = kodi-x11.service
BindsTo = kodi-x11.service

[Service]
Type = oneshot
ExecStart = /opt/autotv/start.sh

kodi-stop.service 除了 ExecStart 部分需要换成对应的 stop.sh 以外没有区别,此处省略。)

然后创建 /etc/systemd/system/kodi-start.timer/etc/systemd/system/kodi-stop.timer 作为计划任务:

[Unit]
Description = Start Kodi in the morning and evening

[Timer]
OnCalendar = *-*-* 07,22:00:00
Persistent = true

[Install]
WantedBy = timers.target

OnCalendar 部分可以有多条,这个计划任务就会在各个指定的时间运行:

[Unit]
Description = Stop Kodi when asleep or left home

[Timer]
OnCalendar = *-*-* 01:00:00
OnCalendar = *-*-* 08:30:00
Persistent = true

[Install]
WantedBy = timers.target

最后,更新 systemd 服务缓存,并启用这两个定时器:

# systemctl daemon-reload
# systemctl enable kodi-start.timer --now
# systemctl enable kodi-stop.timer --now

至此,电视会自动在每天早上 7 点和晚上 22 点开启;凌晨 1 点和早上 8:30 关闭。


现在唯一留下的问题就是 Kodi 会在不知道什么情况下卡住崩溃。或许是因为 CPU 过热导致什么问题;或许是因为电视插件本身会有一些 bug; 或者是其他可能的因素。由于调试这种问题实在是太复杂,所以暂且先按过热处理,观察一段时间再下定论。

发表评论

您的电子邮箱地址不会被公开。