如何在Docker上将ALSA默认设备设置为pulseaudio声音服务器?

我想在使用PulseAudio和ALSA的Docker上的Ubuntu 16.04上播放声音。然而,它输出一个错误"Device or resource busy"。我认为这是因为ALSA的默认设备没有设置为PulseAudio声音服务器(注意:它设置为主机Ubuntu上的PulseAudio)。我如何将默认设备更改为它?例如,我可以通过创建~/.asoundrc或修改/etc/pulse/client.conf来实现吗?
重现步骤:
$ # On the host Ubuntu...
$ aplay -L | head -n9
default
    Playback/recording through the PulseAudio sound server
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
sysdefault:CARD=PCH
    HDA Intel PCH, ALC295 Analog
    Default Audio Device
$ aplay /usr/share/sounds/alsa/Front_Center.wav 
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
$ paplay /usr/share/sounds/alsa/Front_Center.wav  # Success

$ # On the Docker container...
$ sudo docker run -it --device /dev/snd ubuntu:16.04 /bin/bash
root@81af4bf99890:/# apt update
root@81af4bf99890:/# apt install alsa-base alsa-utils pulseaudio
root@81af4bf99890:/# aplay -L | head -n10
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
default:CARD=PCH
    HDA Intel PCH, ALC295 Analog
    Default Audio Device
sysdefault:CARD=PCH
    HDA Intel PCH, ALC295 Analog
    Default Audio Device
root@81af4bf99890:/# aplay /usr/share/sounds/alsa/Front_Center.wav 
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
aplay: main:722: audio open error: Device or resource busy
root@81af4bf99890:/# paplay /usr/share/sounds/alsa/Front_Center.wav 
Connection failure: Connection refused
pa_context_connect() failed: Connection refused

环境

  • 主机:Ubuntu 17.04
  • Docker:17.09.0-ce

附加说明

  • 在我的环境中,Jess的图片也无法工作。这是一个示例日志。

    $ # 当我在主机上播放一些声音时,`jess/spotify`无法播放音乐。
    $ sudo docker run -it \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -e DISPLAY=unix$DISPLAY \
        --device /dev/snd \
        --name spotify \
        jess/spotify
    Gtk-Message: Failed to load module "canberra-gtk-module"
    libGL error: MESA-LOADER: failed to retrieve device information
    libGL error: Version 4 or later of flush extension not found
    libGL error: failed to load driver: i915
    libGL error: failed to open drm device: No such file or directory
    libGL error: failed to load driver: i965
    [1115/043835.051841:ERROR:sandbox_linux.cc(344)] InitializeSandbox() called with multiple threads in process gpu-process.
    [1115/043840.945653:ERROR:web_plugin_impl.cc(38)] Widevine registration is not supported after context initialization
    
    (spotify:1): GLib-GIO-CRITICAL **: g_dbus_connection_send_message: assertion 'G_IS_DBUS_CONNECTION (connection)' failed
    ALSA lib pcm_dmix.c:1052:(snd_pcm_dmix_open) unable to open slave
    

    最后一行表示与ALSA相关的错误。(请注意,当没有其他软件播放声音时,jess/spotify可以播放音乐。这可能是因为在这种情况下声音设备没有被占用。)

  • 虽然我自己回答了这个问题,但我仍想要更复杂的解决方案或对需要某些选项的原因进行详细解释。任何评论都将不胜感激。谢谢。

请尝试这个:https://stackoverflow.com/questions/41083436/how-to-play-sound-in-a-docker-container - Socrates
1@苏格拉底 谢谢你的建议,但我已经尝试过了。那个答案的关键是使用 --device /dev/snd - nekketsuuu
1个回答

感谢fsmunoz的评论,我可以使用pulseaudio在容器中播放声音,而无需修改任何配置文件。要点如下:
  • 设置PULSE_SERVER以让容器的pulseaudio知道服务器地址。
  • 将容器添加到audio中。
  • 共享pulseaudio的cookie

以下是一个可行的示例:

$ sudo docker run -it \
    --device /dev/snd \
    -e PULSE_SERVER=unix:${XDG_RUNTIME_DIR}/pulse/native \
    -v ${XDG_RUNTIME_DIR}/pulse/native:${XDG_RUNTIME_DIR}/pulse/native \
    -v ~/.config/pulse/cookie:/root/.config/pulse/cookie \
    --group-add $(getent group audio | cut -d: -f3) \
    ubuntu:16.04 /bin/bash
root@9c9f7e0db4e3:/# apt update
root@9c9f7e0db4e3:/# apt install alsa-base alsa-utils pulseaudio
root@eed016c1fb61:/# aplay -L | head -n9
default
    Playback/recording through the PulseAudio sound server
null
    Discard all samples (playback) or generate zero samples (capture)
pulse
    PulseAudio Sound Server
sysdefault:CARD=PCH
    HDA Intel PCH, ALC295 Analog
    Default Audio Device
root@9c9f7e0db4e3:/# aplay /usr/share/sounds/alsa/Front_Center.wav 
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
root@9c9f7e0db4e3:/# paplay /usr/share/sounds/alsa/Front_Center.wav  # Success!

注意:但是,我不知道为什么需要cookie。没有cookie,会出现错误ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Access denied

我能在运行在Windows 10主机上的Ubuntu Docker容器中达到类似的目标吗? - Web User
1@WebUser 不好意思,我不清楚具体细节,但有些配置可能会有所不同,比如文件路径等。另外,如果你想按照这个答案操作的话,你需要在Windows上安装PulseAudio。我建议你提一个新问题来询问相关配置信息。 - nekketsuuu
在Ubuntu Server 20.04中,我遇到了这个错误:警告:未设置XDG_RUNTIME_DIR变量。默认为空字符串。 - LIH