A. *_*xxx 33 audio qt alsa pulseaudio docker
这个问题的灵感来自于您是否可以在docker容器中运行GUI应用程序?.
基本的想法是运行带有音频和ui的应用程序(vlc,firefox,skype,...)
我正在使用pulseaudio搜索docker容器,但我发现所有使用pulseaudio流在tcp上的容器.(应用程序的安全沙箱)
在我的情况下,我会优先从容器内的应用程序直接播放音频到我的主机pulseaudio.(没有ssh隧道和臃肿的docker图像)
Pulseaudio因为我的qt app正在使用它;)
A. *_*xxx 32
我花了一些时间才发现需要什么.(Ubuntu的)
我们从docker run命令开始 docker run -ti --rm myContainer sh -c "echo run something"
ALSA:
我们需要/dev/snd和一些硬件访问看起来像.当我们把它放在一起时我们有
docker run -ti --rm \
-v /dev/snd:/dev/snd \
--lxc-conf='lxc.cgroup.devices.allow = c 116:* rwm' \
myContainer sh -c "echo run something"`
Run Code Online (Sandbox Code Playgroud)
在没有lxc标志的新docker版本中你应该使用这个:
docker run -ti --rm \
-v /dev/snd:/dev/snd \
--privileged \
myContainer sh -c "echo run something"`
Run Code Online (Sandbox Code Playgroud)
的PulseAudio:
在这里我们需要基本/dev/shm,/etc/machine-id和/run/user/$uid/pulse.但这并非全部(可能是因为Ubuntu以及他们过去是如何做到的).envirorment变量XDG_RUNTIME_DIR必须在主机系统和docker 容器中相同.您可能还需要,/var/lib/dbus因为某些应用程序正在从此处访问计算机ID(可能只包含指向"真实"计算机ID的符号链接).至少你可能需要~/.pulse一些临时数据的隐藏主文件夹(我不确定这一点).
docker run -ti --rm \
-v /dev/shm:/dev/shm \
-v /etc/machine-id:/etc/machine-id \
-v /run/user/$uid/pulse:/run/user/$uid/pulse \
-v /var/lib/dbus:/var/lib/dbus \
-v ~/.pulse:/home/$dockerUsername/.pulse \
myContainer sh -c "echo run something"
Run Code Online (Sandbox Code Playgroud)
在新的docker版本中,您可能需要添加--privileged.
当然,您可以将它们组合在一起并将其与xServerui转发一起使用,如下所示:https://stackoverflow.com/a/28971413/2835523
仅举几个:
dockerfile uid=$(id -u)得到的用户ID和GID与id -g创建用户脚本:
mkdir -p /home/$dockerUsername && \
echo "$dockerUsername:x:${uid}:${gid}:$dockerUsername,,,:/home/$dockerUsername:/bin/bash" >> /etc/passwd && \
echo "$dockerUsername:x:${uid}:" >> /etc/group && \
mkdir /etc/sudoers.d && \
echo "$dockerUsername ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$dockerUsername && \
chmod 0440 /etc/sudoers.d/$dockerUsername && \
chown ${uid}:${gid} -R /home/$dockerUsername
Run Code Online (Sandbox Code Playgroud)
现在我们有一个 Pipewire,如果您希望 docker 容器内的应用程序使用在主机上运行的 Pipewire 服务器来播放/录制声音,您可以执行以下操作:
graphical.target在现代发行版上,当 systemd 到达并执行登录管理器(gdm、sddm 等)时,Pipewire 就会启动。然后,稍后,当用户登录时,Pipewire 将重新启动以归该用户所有。为了让 docker 容器内的应用程序使用 Pipewire,我们将套接字文件描述符传递给该容器。为此,我们需要知道谁在您的主机上运行 Pipewire 服务器。您可以通过查看管道进程在谁的运行下进行检查,然后找出正确的套接字文件:
testuser@asrock-ubuntu:~$ ps -fp $(pgrep -d, -x pipewire)
UID PID PPID C STIME TTY TIME CMD
testuser 4250 4206 1 13:32 ? 00:00:27 /usr/bin/pipewire
testuser@asrock-ubuntu:~$ id testuser
uid=1000(testuser) gid=1000(testuser) groups=1000(testuser),4(adm),6(disk),24(cdrom),27(sudo),30(dip),46(plugdev),105(input),107(kvm),122(lpadmin),134(lxd),135(sambashare),140(libvirt),64055(libvirt-qemu),997(docker)
Run Code Online (Sandbox Code Playgroud)
所以在我们的例子中,我希望应该有一个套接字文件/run/user/1000/pipewire-0。去检查一下你的系统。
docker run -it -v /run/user/1000/pipewire-0:/tmp/pipewire-0 -e XDG_RUNTIME_DIR=/tmp --rm alpine /bin/ash
Run Code Online (Sandbox Code Playgroud)
apk add pipewire-alsa pipewire alsa-utils
Run Code Online (Sandbox Code Playgroud)
aplay -L,然后运行我们的简单测试以通过该设备播放一些噪音:speaker-test -Dpipewire -c2
Run Code Online (Sandbox Code Playgroud)
此时您应该听到声音。如果没有,请检查主机上的默认 Pipewire 接收器设备。如果您正在运行 Gnome,请打开 Gnome 设置 -> 声音 -> 输出
在容器内,我们现在可以使用 arecord 录制波形文件并使用纯 ALSA 工具进行回放:
arecord --duration=5 --device=pipewire test.wav
aplay --device=pipewire test.wav
Run Code Online (Sandbox Code Playgroud)
pipewire-tools. 我要播放的示例 wav 文件与alsa-utils我们之前安装的 pacakge 一起提供:apk add pipewire-tools
pw-play /usr/share/sounds/alsa/Rear_Center.wav
Run Code Online (Sandbox Code Playgroud)
简而言之,整体设置是这样的:

受您发布的链接的启发,我能够创建以下解决方案。它是我所能得到的那样轻巧。但是,我不确定它是否(1)是安全的,并且(2)是否完全适合您的用例(因为它仍然使用网络)。
paprefs在主机系统上安装,例如sudo apt-get install paprefs在Ubuntu计算机上使用。sudo apt-get install -y pulseaudioexport "PULSE_SERVER=tcp:<host IP address>:<host Pulseaudio port>"。例如,export "PULSE_SERVER=tcp:172.16.86.13:4713"[2]。您可以ifconfig使用pax11publish[1] 查找IP地址,使用Pulseaudio端口查找。PULSE_SERVER以下的环境变量:如果不是,则必须在每个容器启动后对其进行初始化。由于我目前正在研究与OP类似的问题,因此希望使我的方法变得更好的建议将不胜感激。
参考文献:
[1] https://github.com/jlund/docker-chrome-pulseaudio
[2] https://github.com/jlund/docker-chrome-pulseaudio/blob/master/Dockerfile
更新(可能是更好的解决方案):
这也可以使用Unix套接字而不是TCP套接字来工作:
-v /run/user/$UID/pulse/native:/path/to/pulseaudio/socketexport "PULSE_SERVER=unix:/path/to/pulseaudio/socket"该/path/to/pulseaudio/socket可以是任何东西,用于测试目的,我使用/home/user/pulse。
也许它甚至可以在主机上使用与默认套接字相同的路径(照顾$ UID部分),这样最终的解决方案将是-v /run/user/$UID/pulse/native:/run/user/<UID in container>/pulse; 我还没有测试过。
在尝试了此处描述的大多数解决方案后,我发现只有网络上的 PulseAudio真正有效。但是,您可以通过保留身份验证来确保安全。
安装paprefs(在主机上):
$ apt-get install paprefs
Run Code Online (Sandbox Code Playgroud)启动paprefs(PulseAudio 首选项)> 网络服务器 > [X] 启用对本地声音设备的网络访问。
重新启动 PulseAudio:
$ service pulseaudio restart
Run Code Online (Sandbox Code Playgroud)检查它是否有效或重新启动机器:
$ (pax11publish || xprop -root PULSE_SERVER) | grep -Eo 'tcp:[^ ]*'
tcp:myhostname:4713
Run Code Online (Sandbox Code Playgroud)现在使用该套接字:
$ docker run \
-e PULSE_SERVER=tcp:$(hostname -i):4713 \
-e PULSE_COOKIE=/run/pulse/cookie \
-v ~/.config/pulse/cookie:/run/pulse/cookie \
...
Run Code Online (Sandbox Code Playgroud)
检查容器内运行的用户是否有权访问 cookie 文件~/.config/pulse/cookie。
要测试它的工作原理:
$ apt-get install mplayer
$ mplayer /usr/share/sounds/alsa/Front_Right.wav
Run Code Online (Sandbox Code Playgroud)
更多信息可以查看Docker Mopidy项目。
| 归档时间: |
|
| 查看次数: |
25373 次 |
| 最近记录: |