【问题标题】:How to expose audio from Docker container to a Mac?如何将 Docker 容器中的音频暴露给 Mac?
【发布时间】:2017-03-01 09:38:18
【问题描述】:

我知道在 Linux 主机系统上使用脉冲音频是可能的,但 paprefs 是为 linux 而不是为 mac 构建的。

【问题讨论】:

    标签: macos audio docker containers pulseaudio


    【解决方案1】:

    Docker-for-Mac 虚拟机没有任何声音直通设备,因此您无法从这个角度利用任何东西。相比之下,virtualbox 或 vmware fusion VM 确实有能力做直通音频。

    我能够使用以下命令安装 pulseaudio 并在 OSX 上工作:

    brew install pulseaudio
    

    我能够通过运行以下命令来验证这是否有效,并且听到了我的扬声器发出的声音:

    paplay cockatiel.wav
    

    我的下一步是找到具有paplay 副本的图像。我找到了jess/pulseaudio,它似乎打算作为一个pulseaudio 服务器,但我应该也可以将它用作一个客户端

    我在 Archlinux Wiki 上找到了以下关于设置 pulseaudio 网络声音的指南:https://wiki.archlinux.org/index.php/PulseAudio/Examples#PulseAudio_over_network

    通过执行以下操作,我能够使其适应这种情况。我在我的 Mac 上编辑了/usr/local/Cellar/pulseaudio/9.0/etc/pulse/default.pa,并取消了以下两行的注释:

    load-module module-esound-protocol-tcp
    load-module module-native-protocol-tcp
    

    我在我的 Mac 上重新运行 paplay cockatiel.wav 以确保我的更改仍然有效。如果我打错了,pulseaudio 守护进程似乎会按需启动,并将其投诉传回paplay 以打印在我的屏幕上。我对 default.pa 的这些更改仍然有意见,所以我对我的更改没有破坏任何东西感到满意。

    接下来,我在这样的容器中运行 pulseaudio 客户端:

    docker run --rm -v $HOME:$HOME -w $HOME -it \
      -e PULSE_SERVER=192.168.10.23 \
      -e HOME=$HOME --entrypoint paplay \
      jess/pulseaudio $HOME/cockatiel.wav
    

    它的作用是将我的本地主目录作为一个卷运行一个容器。这有两个目的。首先是我的 cockatiel.wav 位于 $HOME 内。第二个是因为客户端和服务器都需要拥有相同的~/.config/pulse/cookie 文件的副本(根据archlinux wiki 指南)。

    PULSE_SERVER 环境变量是我的 OSX 主机的 en0 IP 地址,所以 paplay 知道要连接到什么。

    HOME 环境变量是必需的,因此 paplay 可以找到相同的 ~/.config/pulse/cookie 文件。

    我能够通过 pulseaudio 播放在我的 docker-for-mac 上运行的容器中的声音。

    只要您让~/.config/pulse/cookie 文件出现在正确的位置,您就应该能够播放声音。您不必使用主机卷来完成此操作 - 您也可以执行“docker cp”,甚至可以将 COPY 放入映像中。

    【讨论】:

    • 运行 paplay piano2.wav $ paplay piano2.wav W: [] caps.c: 通常所有额外的功能现在都会被删除,但这是不可能的,因为 PulseAudio 是在没有功能的情况下构建的支持。连接失败:连接被拒绝 pa_context_connect() 失败:连接被拒绝
    • @valentin_nasta 您是否设法解决了在 Mac 上安装 PulseAudio 的问题?
    • 使用当前的 PulseAudio 10.0,运行“pulseaudio --daemonize=false -v”似乎没有启动,之后得到“W: [] socket-util.c: IP_TOS failed: Invalid argument”添加两个 module-esound-protocol-tcp / module-native-protocol-tcp 行。
    【解决方案2】:

    在 Mac 上安装PulseAudio

    brew install pulseaudio
    

    运行守护进程:

    pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon
    

    在您的 Docker 容器中:

    1. 安装 PulseAudio,例如,apt-get install pulseaudio
    2. 设置以下环境变量:ENV PULSE_SERVER=docker.for.mac.localhost

    运行时,将~/.config/pulse 目录与容器共享以进行身份​​验证。

    你可以运行一个测试看看它是否像这样工作:

    docker run -it -e PULSE_SERVER=docker.for.mac.localhost -v ~/.config/pulse:/home/pulseaudio/.config/pulse --entrypoint speaker-test --rm jess/pulseaudio -c 2 -l 1 -t wav
    

    【讨论】:

    • 原来我在 OS X 可访问性设置中设置了立体声 -> 单声道。立体声效果很好。谢谢!
    • 在最近发布的 Docker for Mac(和 Windows)中,他们将魔术主机名更改为 host.docker.internal,我建议将 -v 旧语法更改为较新的 --mount type=bind,source=~/.config/pulse,target=/home/pulseaudio/.config/pulse 以避免创建如果您尚未运行 brew install pulseaudio 并对其进行配置,则主机上的配置为 root >
    • 谢谢。我花了一段时间才弄清楚为什么测试可以正常工作,但我自己的容器却没有:mount ("-v ~/.config/pulse:/home/pulseaudio/.config/pulse") 指向jess/pulseaudio 图像创建的“pulseaudio”用户的主目录。我不得不将挂载更改为指向我用户的主目录。
    • @dragon788 尝试使用您的安装建议引发错误(说它需要绝对路径)。我设法让它工作,奇怪的是扬声器测试没有产生任何输出
    最近更新 更多