在Linux的登录界面使用Sunshine串流
在去年,我在博客里写了一篇关于远程串流的文章。其中提到了在 Linux 上串流的一个问题:
但是在 Linux 平台,想让 Sunshine 虽系统启动有点麻烦。如果用 KDE 的自动启动程序的话,SDDM 登录界面它还是没启动,就没法远程输密码进系统。如果搞成系统级服务的话,就得让它以 root 身份运行,总感觉不太好。
最后想到了一个比较折中的方法:让 SDDM 开机时自动登录用户会话,同时给 KDE 设置一个自动启动脚本,在脚本中让 KDE 登录后立即锁屏。虽然感觉这个做法有点草台班子,但实际操作也挺简单,也能远程输密码,就先用这个方案了。
这个方法大体上算是勉强能用,但是开着自动登录总归是是有点不爽。而且在系统中偶尔需要注销用户重新登录,这样每次重新登录之后就又会触发自己写的自动锁屏脚本,所以就需要输两次密码,还是有点烦人了。
不久前,在 Sunshine 开发者官方博客上看到了这样的一篇文章:Autostart Sunshine on Boot without Auto-Login,文章中使用了一个很绕的方法让系统开机后自动 ssh 到本地用户,然后触发 sunshine 的启动脚本。虽然没太看懂,但大致上就是开机时先用系统级别的 systemd 开一个 sunshine,登录之后再切换成用户的 systemd 来运行 sunshine。
那能不能不用 ssh,直接让 systemd 用 root 身份启动一个 sunshine 呢?
其实是可以的。可以直接验证一下:注销之后停在 SDDM/GDM 的登录界面。然后切 tty 进 root 之后运行 sunshine,是可以正常运行并且串流到登录界面的。LizardByte 的文章中也有提到,只是这样不能串流音频也没有 tray icon,所有用户登录之后还是要切回 systemd user 的 sunshine 服务。
参照以上内容,我们可以先创建一个服务 :
文件:/etc/systemd/system/sunshine-sddm.service
1 | [Unit] |
这个服务是为了开机之后能正常连接到登录界面。这里我使用的 Display Manager 是 SDDM,所以就让它在 SDDM 服务之后启动了,用 GDM 或者其他 DM 也是类似。
这里还设置了 HOME 环境变量,是为了这个以 root 运行的 sunshine 能复用自己用户的 sunshine 的配置文件,这样的话 Moolight 那边就不会需要显示两个设备了,使用同一个设备连接即可。记得把 /home/username
替换为自己的家目录。
在用户登录之后,切回用户的 sunshine 就是直接参照上面文章中的内容了。但是这里我们不直接修改 sunshine 的 service,使用使用 systemd override。这样可以防止 sunshine 更新之后把我们修改的内容覆盖掉。
在用户桌面环境下执行命令:
1 | systemctl --user edit sunshine |
然后按照下面的内容填写覆盖选项:
1 | ## Editing /home/revincx/.config/systemd/user/sunshine.service.d/override.conf |
之后,覆盖的选项内容就会保存到 /home/usename/.config/systemd/user/sunshine.service.d/override.conf。
这里的覆盖内容主要是添加 Hook,让用户层的 sunshine 在启动前关闭 root 层的 sunshine,在结束后开启 root 层的 sunshine。
但是用户在执行 systemctl 的时候是要输密码授权的,为了跳过用户登录之后又要输入一次密码的步骤,这里需要单独写一条 polkit 规则:
创建文件:/etc/polkit-1/rules.d/sunshine-sddm.rules
1 | polkit.addRule(function(action, subject) { |
添加这条规则之后,重启一下 polkit.service,之后普通用户使用 systemctl 来开关 sunshine-sddm.service 就不用输密码了。
对了,最后别忘了 systemctl enable sunshine-sddm
以及 systemctl --user enable sunshine
。
完成了以上所有步骤之后,你就可以在使用 WoL 远程唤醒电脑之后,顺利地使用 Moonlight 串流到登录界面了。登录之后会断开一下连接,再重新连接就可以使用桌面了。
小彩蛋
在用 hexo 创建这篇文章之前,发现 git 仓库里有一个未跟踪的文件:
1 | $ git status |
我去,这是什么来着,我怎么一点印象没有了呢(