web-dev-qa-db-ja.com

Dockerコンテナ内のChromeへのマイク入力をエミュレートする

バックグラウンド

Dockerコンテナ内でSeleniumによって制御されるChromeで実行されているWebRTCWebアプリケーションへの入力を制御しようとしています。

これは、WebRTCアプリケーションの自動テストの一部です。
テストの一環として、想定されていたときに音声が反対側で受信されていることを確認できる必要があります。
基本的に、クライアントがミュートになっていない限り、一方のクライアントが発言すると、もう一方のクライアントがそれを聞き、逆も同様です。

これで、コマンドラインパラメーターを使用して開始することで、マイク(およびカメラ)入力をエミュレートするChromeを簡単に取得できます。

--use-fake-ui-for-media-stream
--use-fake-device-for-media-stream

これには、デフォルトのサンプルに多くの無音が含まれている(検出が難しい)という問題があります。より一貫性のあるオーディオを自分のオーディオファイルに提供することで、これを解決できます。

--use-file-for-fake-audio-capture=/opt/media/audio1.wav

ただし、これには別の問題があります。Chromeが同時にオーディオを送信および受信している場合、受信したオーディオは、Chromeのエコーキャンセル機能の一部として、完全に無音になり、ほぼ完全に無音になります。(エコーキャンセルは、Chrome自体の一部ではなく、WebRTCアプリケーションの一部として設定されます。テストを容易にするために、テスト対象のコードに変更を加えたくありません。)
2つの異なるサンプル(クライアントごとに1つ)を使用すると、わずかに役立ちますが、それほどではありません。

本当の問題は、両方のクライアントが実行している間ノンストップで「話す」ことです。これは、前述のエコーキャンセレーションのためにオーディオを台無しにします。また、通常はテストしないため、テストする現実的なシナリオではありません。常にお互いに話し合います。

理論的には、ノイズ/サイレンスの意図的なセクションが含まれる特別に作成されたサンプルを使用できますが、これらのサンプルをクライアント間で調整し、テスト検証を行うことは悪夢です。

問題

私が本当に必要としているのは、オンデマンドでクライアントへのオーディオの再生を開始および停止できるようにすることです。

Chromeで偽のメディアストリームを制御する方法はないようです。そのため、おそらく、Dockerコンテナー内に偽の「マイク」オーディオ入力デバイスを作成し、それを制御するのが私の最善の方法です。

標準のLinuxでは、pulseaudioを使用してオーディオ出力をキャプチャデバイスとしてループバックできます。これは有望に見えますが、Dockerコンテナ内でそれを使用する方法がわかりません。
Dockerコンテナーには、それを使用するためのオーディオデバイスすらありません。
ホストマシンのオーディオハードウェアを使用するようにDockerを設定する方法に関するさまざまなガイドを見つけましたが、これらのコンテナーはeSXIサーバーで実行されており、サウンドがないため、あまり役に立ちません使用するカード。
Pulseaudioは仮想デバイスもサポートしていますが、それらが機能するにはドライバー/カーネルモジュールが必要です。私は間違っているかもしれませんが、Dockerコンテナー内でそれらを使用できるとは思いません。

質問

上記が少し冗長である場合は申し訳ありませんが、私は問題とすでに調べたさまざまな方向性を説明しようとしていました。

では、偽のキャプチャデバイスを使用するか、他の方法で、Dockerコンテナ内のChromeのキャプチャデバイスへのオーディオ入力を制御できる方法を誰かが知っていますか?

7
Nameless Voice

私はこれに対する解決策を見つけることができました。基本的な概念はかなり単純ですが、回避すべきいくつかの落とし穴があります。

このソリューションには、仮想オーディオソースを作成するpulseaudioの機能と、そのオーディオデバイスでメディアを再生するためのpaplayツールを利用することが含まれます。

Dockerコンテナーのセットアップ

すでに使用しているUbuntu/Chrome/Seleniumイメージに基づいて独自のDockerイメージを作成し、pulseaudioパッケージをインストールし、エントリポイントを微調整して起動し、オーディオファイルを追加して再生する必要がありました。

dockerfile:

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

次に、標準のSeleniumスタートアップエントリポイントを開始する前に、pulseaudioサーバーを起動してカスタムオーディオソースを構成するためのカスタムエントリポイントが必要でした。
ここには2つの仮想デバイスがあり、1つを仮想マイクにパイプすることなくオーディオ再生に使用できます。

entrypoint.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

「seluser」ユーザーとして実行されているChromeのSelenium制御インスタンスでオーディオデバイスを使用したいので、TCP(localhost接続の場合のみ)を介して仮想サウンドカードを公開する必要がありました。 )、次に、そのネットワークサウンドカードを使用するようにセルユーザーを構成します。追加のセットアップは必要ありません。仮想ソースはDockerイメージ上の唯一のオーディオ入力デバイスであるため、Chromeは自動的に使用します。すべて残っているのは、Dockerコンテナーの構築と実行です。

オーディオの再生

コンテナーが実行されたら、paplayを使用してメディアを仮想出力デバイスに送信しました。仮想出力デバイスは、上記で「MicOutput」と名付けました。これは、execコマンドを介してトリガーできます。

docker exec -t -i TestContainerName paplay --device=MicOutput /opt/media/audio2.wav

以上です。

もちろん、Selenium WebDriverを構成するときにChrome Capbilitiesで "--use-fake-ui-for-media-stream"オプションを使用して、Seleniumが尋ねましたが、「-use-fake-device-for-media-stream」オプションを使用しないようにしてください。このオプションを使用すると、偽の入力デバイスがChromeの組み込みデバイスに置き換えられます。

スペースピクルの答えのおかげで この質問 私を正しい軌道に乗せてくれて、Eli Billauerの投稿 複数のユーザーにPulseオーディオを使用することについて

7
Nameless Voice