Nam*_*ice 8 audio linux microphone google-chrome docker
我正在尝试控制在 Docker 容器内由 Selenium 控制的 Chrome 上运行的 WebRTC Web 应用程序的输入。
这是 WebRTC 应用程序自动化测试的一部分。
作为测试的一部分,我需要能够检查另一端是否在应有的时候接收到音频。
基本上,我想检查如果一个客户说话,另一个客户听到它,反之亦然,除非客户处于静音状态。
现在,通过使用命令行参数启动 Chrome,我可以轻松地让 Chrome 模拟麦克风(和摄像头)输入:
--use-fake-ui-for-media-stream
--use-fake-device-for-media-stream
Run Code Online (Sandbox Code Playgroud)
这有一个问题,即默认样本中有很多静音(更难检测)。我可以通过提供我自己的音频文件更一致的音频来解决这个问题:
--use-file-for-fake-audio-capture=/opt/media/audio1.wav
Run Code Online (Sandbox Code Playgroud)
但这还有另一个问题——如果 Chrome 同时发送和接收音频,作为 Chrome 回声消除功能的一部分,接收到的音频会被严重破坏,几乎完全静音。(回声消除设置为 WebRTC 应用程序的一部分,而不是 Chrome 本身的一部分,我不想对正在测试的代码进行更改以方便测试。)
使用两个不同的示例(每个客户端一个)有一点帮助,但不是很大。
真正的问题是,只要他们正在运行,这两个客户端就会不停地“说话”,由于上述回声消除,这既会弄乱音频,也不是要测试的现实场景,因为人们通常不会不断地互相交谈。
从理论上讲,我可以使用特制的样本,其中包含有意的噪声/静音部分,但是在客户端之间对齐这些样本并与测试验证保持一致将是一场噩梦。
我真正需要的是能够根据需要开始和停止向客户端播放音频。
似乎没有任何方法可以控制 Chrome 中的假媒体流,所以我最好的选择似乎是在 Docker 容器内以某种方式创建一个假的“麦克风”音频输入设备,并控制它。
在标准 Linux 上,您可以使用 pulseaudio 将音频输出循环回作为捕获设备,这看起来很有希望,但我不知道如何在 Docker 容器中使用它。
Docker 容器甚至没有任何可以使用的音频设备。
我找到了关于如何设置 Docker 以使用主机的音频硬件的各种指南,但这并不是很有用,因为这些容器在 eSXI 服务器上运行并且没有任何声卡可以使用。
Pulseaudio 也支持虚拟设备,但那些需要驱动程序/内核模块才能工作。我可能是错的,但我认为你不能在 Docker 容器中使用它们。
对不起,如果上面有点罗嗦,但我试图解释这个问题和我已经研究过的各个方向。
那么,有没有人知道我可以使用假的捕获设备或通过其他方式控制音频输入到 Docker 容器内 Chrome 捕获设备的方法?
我设法找到了解决方案。基本概念相当简单,但它有几个问题需要解决。
该解决方案涉及利用pulseaudio 创建虚拟音频源的能力,以及利用paplay 工具将媒体播放到该音频设备中。
我需要基于我已经在使用的 Ubuntu/Chrome/Selenium 映像制作自己的 Docker 映像,以安装 pulseaudio 包,调整入口点以启动它,并添加一些音频文件以进行播放。
码头档案:
FROM selenium/standalone-chrome-debug
# Install pulse audio
RUN apt-get -qq update && apt-get install -y pulseaudio
# Copy some media files into place
RUN mkdir -p /opt/media
COPY audio1.wav /opt/media/audio1.wav
COPY audio2.wav /opt/media/audio2.wav
# Use custom entrypoint
COPY entrypoint.sh /opt/bin/entrypoint.sh
ENTRYPOINT /opt/bin/entrypoint.sh
Run Code Online (Sandbox Code Playgroud)
然后,在启动标准 Selenium 启动入口点之前,我需要一个自定义入口点来启动脉冲音频服务器并配置一个自定义音频源。
这里有两个虚拟设备,因此一个可以用于音频播放,而无需通过管道传输到虚拟麦克风。
入口点.sh
# Load pulseaudio virtual audio source
pulseaudio -D --exit-idle-time=-1
# Create virtual output device (used for audio playback)
pactl load-module module-null-sink sink_name=DummyOutput sink_properties=device.description="Virtual_Dummy_Output"
# Create virtual microphone output, used to play media into the "microphone"
pactl load-module module-null-sink sink_name=MicOutput sink_properties=device.description="Virtual_Microphone_Output"
# Set the default source device (for future sources) to use the monitor of the virtual microphone output
pacmd set-default-source MicOutput.monitor
# Create a virtual audio source linked up to the virtual microphone output
pacmd load-module module-virtual-source source_name=VirtualMic
# Allow pulse audio to be accssed via TCP (from localhost only), to allow other users to access the virtual devices
pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1
# Configure the "seluser" user to use the network virtual soundcard
mkdir -p /home/seluser/.pulse
echo "default-server = 127.0.0.1" > /home/seluser/.pulse/client.conf
chown seluser:seluser /home/seluser/.pulse -R
# Start Selenium-Chrome-Standalone
/opt/bin/entry_point.sh
Run Code Online (Sandbox Code Playgroud)
因为我想在以“seluser”用户身份运行的由 Selenium 控制的 Chrome 实例中使用音频设备,所以我需要通过 TCP 公开虚拟声卡(仅适用于本地主机连接),然后配置 seluser 以使用那个网络声卡。无需额外设置。虚拟源是 Docker 镜像上唯一的音频输入设备,因此 Chrome 会自动使用它。剩下的就是构建和运行 docker 容器。
容器运行后,我使用 paplay 将媒体发送到虚拟输出设备,我在上面将其命名为“MicOutput”。这可以通过 exec 命令触发:
docker exec -t -i TestContainerName paplay --device=MicOutput /opt/media/audio2.wav
Run Code Online (Sandbox Code Playgroud)
就是这样。
当然,在配置我的 Selenium WebDriver 时,我还需要在 Chrome Capbilities 中使用“--use-fake-ui-for-media-stream”选项,让 Selenium 无需询问即可使用该设备,但必须确保不要使用“--use-fake-device-for-media-stream”选项,因为这会用 Chrome 的内置设备替换假输入设备。
感谢 spacepickle 对这个问题的回答让我走上了正轨,以及 Eli Billauer关于为多个用户使用 Pulse 音频的帖子
| 归档时间: |
|
| 查看次数: |
5889 次 |
| 最近记录: |