Воспроизведение звука в контейнере Docker на WSL в Windows 11

#windows #docker #audio #wsl-2

Вопрос:

Более новые версии Windows (сборка 21364 или более поздняя версия) включают поддержку графического интерфейса в WSL2, включая полную поддержку звука. Это довольно удивительно.

Учитывая, что WSL2 теперь поддерживает аудио, как нам затем заставить аудио работать внутри контейнера Docker, работающего в Windows, с помощью движка WSL2 Docker?

На хосте Linux вы можете просто вызвать образ Docker, например . --device /dev/snd

Какова эквивалентная команда для запуска образа Docker с поддержкой звука из командной строки Windows?

Комментарии:

1. Не то чтобы я пробовал, но если ваша информация верна, вы должны быть в состоянии сделать --device /dev/snd это изнутри WSL.

2. К сожалению, /dev/snd не существует в обновленном WSL. Я полагаю, что ALSA отправляет звук непосредственно в Pulseaudio, который затем перенаправляется в Windows.

Ответ №1:

В WSL отсутствует /dev/snd или отсутствует прямая эмуляция звукового оборудования, доступная даже в новой установке Windows 11. Вместо этого, новейшая версия WSL обеспечивает аудиовыход, указывая клиентам PulseAudio на внешний сервер PulseAudio через встроенный сокет /mnt/wslg/ . Этот сервер работает на еще одном дистрибутиве Linux calleed WSLg, который запускается внутри Windows с единственной целью передачи аудио и графических данных между вашим дистрибутивом WSL и Windows.

Это выглядит примерно так:

 Docker container <-> WSL <-> WSLg <-> Windows 11
 

Фактический сервер PulseAudio находится в WSLg. Расположение сокета хранится в переменной среды PULSE_SERVER :

 # On WSL   
echo $PULSE_SERVER
/mnt/wslg/PulseServer
 

Итак, помимо того, чтобы убедиться, что в вашем файле Dockerfile установлена базовая установка PulseAudio ( RUN apt-get install -y pulseaudio или ее эквивалент), все, что вам нужно сделать, это вызвать образ следующим образом:

В WSL:

 docker run -t -i -e "PULSE_SERVER=${PULSE_SERVER}" -v /mnt/wslg/:/mnt/wslg/ image_name
 

Или из командной строки Windows, например:

 wsl docker run -t -i -e "PULSE_SERVER=/mnt/wslg/PulseServer" -v /mnt/wslg/:/mnt/wslg/ image_name
 

Или

 docker run -t -i -e "PULSE_SERVER=/mnt/wslg/PulseServer" -v \wsl$Ubuntumntwslg:/mnt/wslg/ image_name