使用SystemD运行python-socketio以在后台播放声音

时间:2019-05-03 09:24:15

标签: python socket.io subprocess systemd

我的 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客户端,它应侦听“监听”和“播放”之类的事件。代码的主要部分如下所示:

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语句。

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

1 个答案:

答案 0 :(得分:0)

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