如何在 Ubuntu 上从 systemd 服务播放声音?

kab*_*oom 5 sound systemd

我尝试从 Ubuntu 上的服务播放声音:

tim@timpc:~$ uname -a Linux timpc 5.4.0-91-generic #102-Ubuntu SMP 11 月 5 日星期五 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

这是服务定义:

tim@timpc:~$ cat /etc/systemd/system/alarmd.service
# Datei /etc/systemd/system/alarmd.service
[Unit]
Description=alarmd service
Wants=sound.target
After=sound.target

[Service]
Type=oneshot
Environment="DISPLAY=:0"
User=tim
;ExecStart=/home/tim/Dokumente/super/alarmd/build/release/dist/alarmd --sound /usr/local/share/alarmd/a.wav
ExecStart=mplayer /usr/local/share/alarmd/a.wav

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

我这样启动服务:

sudo systemctl start alarmd.service
Run Code Online (Sandbox Code Playgroud)

...并得到这个输出:

tim@timpc:~$ journalctl -S today -u alarmd.service
-- Logs begin at Wed 2021-08-11 09:41:59 CEST, end at Sun 2021-12-05 16:28:06 CET. --
Dez 05 16:28:06 timpc systemd[1]: Starting alarmd service...
Dez 05 16:28:06 timpc mplayer[13082]: MPlayer 1.3.0 (Debian), built with gcc-9 (C) 2000-2016 MPlayer Team
Dez 05 16:28:06 timpc mplayer[13082]: do_connect: could not connect to socket
Dez 05 16:28:06 timpc mplayer[13082]: connect: No such file or directory
Dez 05 16:28:06 timpc mplayer[13082]: Failed to open LIRC support. You will not be able to use your remote control.
Dez 05 16:28:06 timpc mplayer[13082]: Terminal type `unknown' is not defined.
Dez 05 16:28:06 timpc mplayer[13082]: Playing /usr/local/share/alarmd/a.wav.
Dez 05 16:28:06 timpc mplayer[13082]: libavformat version 58.29.100 (external)
Dez 05 16:28:06 timpc mplayer[13082]: Audio only file format detected.
Dez 05 16:28:06 timpc mplayer[13082]: Load subtitles in /usr/local/share/alarmd/
Dez 05 16:28:06 timpc mplayer[13082]: ==========================================================================
Dez 05 16:28:06 timpc mplayer[13082]: Opening audio decoder: [pcm] Uncompressed PCM audio decoder
Dez 05 16:28:06 timpc mplayer[13082]: AUDIO: 44100 Hz, 2 ch, s16le, 1411.2 kbit/100.00% (ratio: 176400->176400)
Dez 05 16:28:06 timpc mplayer[13082]: Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
Dez 05 16:28:06 timpc mplayer[13082]: ==========================================================================
Dez 05 16:28:06 timpc mplayer[13082]: AO: [pulse] Init failed: Connection refused
Dez 05 16:28:06 timpc mplayer[13082]: Failed to initialize audio driver 'pulse'
Dez 05 16:28:06 timpc mplayer[13082]: [AO_ALSA] alsa-lib: pcm_hw.c:1715:(snd_pcm_hw_open) open '/dev/snd/pcmC0D0p' failed (-2): No such file or directory
Dez 05 16:28:06 timpc mplayer[13082]: [AO_ALSA] alsa-lib: pcm_dmix.c:1089:(snd_pcm_dmix_open) unable to open slave
Dez 05 16:28:06 timpc mplayer[13082]: [AO_ALSA] Playback open error: No such file or directory
Dez 05 16:28:06 timpc mplayer[13082]: Failed to initialize audio driver 'alsa'
Dez 05 16:28:06 timpc mplayer[13082]: [AO SDL] Samplerate: 44100Hz Channels: Stereo Format s16le
Dez 05 16:28:06 timpc mplayer[13082]: [AO SDL] using aalib audio driver.
Dez 05 16:28:06 timpc mplayer[13082]: [AO SDL] Unable to open audio: No available audio device
Dez 05 16:28:06 timpc mplayer[13082]: Failed to initialize audio driver 'sdl:aalib'
Dez 05 16:28:06 timpc mplayer[13082]: Could not open/initialize audio device -> no sound.
Dez 05 16:28:06 timpc mplayer[13082]: Audio: no sound
Dez 05 16:28:06 timpc mplayer[13082]: Video: no video
Dez 05 16:28:06 timpc mplayer[13082]: Exiting... (End of file)
Dez 05 16:28:06 timpc systemd[1]: alarmd.service: Succeeded.
Dez 05 16:28:06 timpc systemd[1]: Finished alarmd service.
Run Code Online (Sandbox Code Playgroud)

我应该如何定义服务以便播放声音?

该命令本身有效:

tim@timpc:~$ mplayer /usr/local/share/alarmd/a.wav
MPlayer 1.3.0 (Debian), built with gcc-9 (C) 2000-2016 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing /usr/local/share/alarmd/a.wav.
libavformat version 58.29.100 (external)
Audio only file format detected.
Load subtitles in /usr/local/share/alarmd/
==========================================================================
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 44100 Hz, 2 ch, s16le, 1411.2 kbit/100.00% (ratio: 176400->176400)
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
==========================================================================
AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...
A:   9.1 (09.1) of 233.0 (03:53.0)  0.0% 


MPlayer interrupted by signal 2 in module: play_audio
A:   9.2 (09.1) of 233.0 (03:53.0)  0.0% 

Exiting... (Quit)
Run Code Online (Sandbox Code Playgroud)

use*_*489 6

在当前版本的 Ubuntu 中,声音通常由脉冲音频服务器处理。如果您从登录的会话中运行声音播放器,那么播放器将通过环境变量XDG_RUNTIME_DIR和/或PULSE_RUNTIME_PATH. 为了使 systemd(或 cron)中的作业能够找到服务器,它将需要这些值。

幸运的是,这些值可以通过用户名进行预测,并且如果是同一用户,则不应从一次登录到下一次登录而更改。(设置DISPLAY是一个很好的尝试,但不是正确的会话变量。)

例如,如果用户 tim 是系统上的第一个用户,则该用户的 uid 可能是 1000(检查 /etc/passwd 或键入id或检查当前值。)将以下内容添加到您的 systemd 文件中:(不确定其中之一是否就足够好了,或者如果您两者都需要,则可能取决于版本。)

Environment="XDG_RUNTIME_DIR=/run/user/1000"
Environment="PULSE_RUNTIME_PATH=/run/user/1000/pulse/"
Run Code Online (Sandbox Code Playgroud)

由于这仅在您以任何方式登录时才有效,因此 systemd 文件的替代方案是在作为 gnome 会话的一部分启动的脚本中启动您的服务。如果您这样做,您根本不需要担心会话变量。