如何将 Docker 容器中的音频暴露给 Mac?
Posted
技术标签:
【中文标题】如何将 Docker 容器中的音频暴露给 Mac?【英文标题】:How to expose audio from Docker container to a Mac? 【发布时间】:2017-03-01 09:38:18 【问题描述】:我知道在 Linux 主机系统上使用脉冲音频是可能的,但 paprefs
是为 linux 而不是为 mac 构建的。
【问题讨论】:
【参考方案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 容器中:
-
安装 PulseAudio,例如,
apt-get install pulseaudio
。
设置以下环境变量: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 尝试使用您的安装建议引发错误(说它需要绝对路径)。我设法让它工作,奇怪的是扬声器测试没有产生任何输出以上是关于如何将 Docker 容器中的音频暴露给 Mac?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以将 USB 设备暴露给 LXC/Docker 容器?
如何让不同的 Docker 容器相互通信而不将端口暴露给全世界
如何在没有端口映射的情况下将 docker 容器的 ip 和端口暴露给外部 docker 主机?
Postgres 9.1 的 Docker 容器未将端口 5432 暴露给主机