运行 python-socketio with SystemD 在后台播放声音

Running python-socketio with SystemD to play sounds at background

我的 SystemD 服务 文件如下所示:

[Unit]
Description=XXX
After=sound.target network.target
Wants=sound.target

[Service]
ExecStart=/usr/bin/python3 -u raspberry.py
WorkingDirectory=/home/pi/Desktop
Restart=always
User=pi
PrivateTmp=true

[Install]
Alias=XXX
WantedBy=multi-user.target

python 脚本是经典的 python-socketio 客户端,它应该侦听 "listen" 和 "play" 等事件.代码的主要部分如下所示:

import subprocess
import socketio

HOST = "https://XXX.ngrok.io"
sio = socketio.Client(engineio_logger=True)

...

@sio.on('play')
def play(data):
    print("play")
    subprocess.call(["espeak", "'Not working'"])

if __name__ == '__main__':
    subprocess.call(["espeak","'Initialized'"]) 
    sio.connect(HOST)
    sio.wait()

当我在启动时将服务设置为 运行 时,会执行第一个 espeak 调用并建立与我的服务器的套接字连接,但是如果我(通过我的服务器)发送一个事件,则第二个调用espeak 不工作(没有声音)。如果我通过 journalctl -u XXX 查看日志,我将看到调用该函数是因为执行了 print 语句。

我想到的是,这是因为 运行 从另一个线程调用子进程,但我不确定..有什么想法吗?

解决方案与我在 Raspberry Pi forum 的另一个问题有关。主要问题是 root 无法播放声音。当我调试这个问题时,我发现因为 User=pi 服务是以 user pi 启动的。但是当我在 @sio.on('play') 部分调用 subprocess.call 时,它被称为 user root。它只发生在 @sio.on('play') 部分。如果我在 if __name__ == '__main__': 部分这样做,调用是在 pi 用户下进行的。仍然不知道为什么会这样,但解决方案不是使用 AIY 帽子版本的 Raspbian,而是经典版本 Raspbian Stretch Lite.