- PVSM.RU - https://www.pvsm.ru -
Однажды я заметил, что довольно много времени я провожу на кухне, куда звук от колонок, расположенных в комнате доходит плохо. И тогда мне захотелось сделать хороший бесшумный плеер, способный синхронно воспроизводить музыку в нескольких комнатах. Конечно проблему можно было решить простым поворотом регулятора громкости, но этот способ был отброшен как негуманный по отношению к соседям. Другой важный момент заключался в том, что я хотел использовать те же колонки для вывода звука с компьютера. Зачем мне иметь несколько комплектов аккустики в одной комнате?
Пост получился довольно длиннный, так как я старался уделить внимание соображениям, по которым я выбирал то или иное решение.
Программ, способный синхронно воспроизводить звук очень мало. Наше ухо может различать малейшие отклонения и мы начинаем слышать эхо. Удовольствия столько же, как от объявлений прибывающих поездов через громкую связь на вокзале в глубинке. Хороший результат показывают две звуковые системы: jack [1] и PulseAudio [2]. Говорят, что еще неплохо работает squeezebox [3]. Я также пробовал mplayer и vlc, но добиться от них приемлемой синхронности не получилось. Vlc неплохо справляется с видеопотоком, если использовать RTP multicast [4], но у звука наблюдается заметное эхо. А с video on demand [5] синхронизации вообще нет, так как каждый клиент получает отдельный поток. Mplayer просто ужасно тормозит, если включить udp синхронизацию.
Так что, если нет необходимости синхронно отображать видео, то jack или PulseAudio являются хорошим выбором за счет своей гибкости. Если же нужно видео… дайте мне знать, если найдется что-то действительно работающее.
После длительных поисков оказалось, что никакой борьбы между ними нет: их писали для совсем разных целей. Мне не нужны очень короткие задержки и огромная гибкость в коммутации потоков во время работы для того, чтобы слушать музыку. Зато я хочу меньше грузить CPU и не гонять пакеты по сети, если ничего не воспроизводится. Все, что мне надо — это включать и выключать заранее определенные выходы. Поэтому в моём случае PulseAudio является предпочтительным выбором.
Hint: Первым делом надо правильно настроить часы. Если они будут плохо синхронизированны между устройствами, могут возникать странные баги. Поэтому везде надо установить ntpd.
Настроить синхронное воспроизведение можно несколькими способами. Можно использовать module-combine-sink совместно с module-tunnel-sink, а можно использовать широковещательные rtp потоки. Я выбрал module-combine-sink, так как он дает значительно меньшую зарежку. Но он не работает через WiFi, а rtp может быть и будет. Но я не люблю WiFi, я люблю проводочки.
Еще одна тонкость заключается в том, что PulseAudio может работать либо как общесистемный демон, либо для каждого пользователя отдельно. Последнее является предпочтительным решением [6], в основном из-за соображений безопасности, например, чтобы пользователи не могли отключать или перенаправлять чужие потоки. Но если речь идет о клиенте без X11, то остайтся толкьо системный режим. А проблемы с безопасностью… так это же ровно то, что мне надо: общий звуковой сервер для нескольких доверенных пользователей.
Если вы выбрали систеный режим, то не забудте добавить себя в группу pulse-access. Файлы настроек находятся в каталоге /etc/pulse/. Для системного режима это system.pa, а для пользовательского default.pa.
Это устройства, к которым подключены усилители. На них надо разрешить удаленный доступ, так что добавляем в конфиг module-native-protocol-tcp:
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16
На устройстве, с которого будет идти звуковой поток, надо настроить удаленные выводы. Для каждого выходного устройства (кроме локальных выходов) добавляем строки следующего вида:
load-module module-tunnel-sink server=<output device address>
Теперь нужно научиться динамически включать и выключать их. PulseAudio посылает данные даже на заглушенные (muted) каналы, но не посылает на выключенные (suspended) выходы. Чтобы не выключать выво звука для всех приложений, создадим промежуточные выходы для каждого реального выхода:
load-module module-combine-sink sink_name=kitchen_mpd slaves=tunnel-sink.u2k.home
load-module module-combine-sink sink_name=hall_mpd slaves=alsa_output.usb-ESI_Audiotechnik_GmbH_Dr._DAC_nano-01-nano.analog-stereo
И, наконец, объединим эти выходы в один:
load-module module-combine-sink sink_name=mpd_sink slaves=kitchen_mpd,hall_mpd
Теперь, после перезапуска PulseAudio можно включать и выключать отдельные выходы командами вида
# Выключить
pactl suspend-sink hall_mpd 1
# Включить
pactl suspend-sink hall_mpd 0
Ура! Натсраиваемый выход, синхронно воспроизводящий звук через несколько выходных устройств, подключенных по сети, готов.
Теперь к этому выходу надо подключить какой-нибудь проигрыватель. Я выбрал MPD, так как им можно удаленно управлять почти с любого устройства. Это удобно, когда музыку слушаешь на кухне, а компьютер стоит в комнате. Настройка очень простая:
audio_output {
type "pulse"
name "Pulse"
server "u2.home" # optional
sink "mpd_sink"
}
Но при наличии нескольких выходов хочется еще ими и управлять через интерфейс MPD. Я написал небольшой хак [7] для MPD, который позволяет это делать. Это модифицированный NullOutput, который выполняет произвольные команды при включении и выключении. Остается настроить эти выходы на соответсвующие вызовы pactl и спрятать основной (первый) выод другим маленьким хаком.
audio_output {
type "exec"
name "Зал"
enable "pactl suspend-sink hall_mpd 0"
disable "pactl suspend-sink hall_mpd 1"
}
audio_output {
type "exec"
name "Кухня"
enable "/usr/bin/pactl suspend-sink kitchen_mpd 0"
disable "/usr/bin/pactl suspend-sink kitchen_mpd 1"
}
На стационарном компьютере я прописал в /etc/pulse/client.conf
default-server = u2.home
В результате все приложения связываются с удаленным звуковым сервером напрямую. Работает безотказно.
Основная проблема, с которой пришлось столкнуться — это ненадежность. Если пропадает сетевое соединение PulseAudio удаляет соответствующие выходы и не пересоздает их. Приходится перезапускать вручную.
Другая проблема заключается в том, что состояние выходов в MPD и PulseAudio может не совпадать. Приходится лишний раз наживать на кнопку, чтобы включить или выключить звук.
Я могу слушать музыку за завтраком и за ужином. Более того, музыка хорошо слышна в большей части квартиры и играет не тихо и не громко. По-желанию отдельные зоны можно отключать. Управлять ей легко и просто. В общем, коте одобряет:
Автор: kibergus
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/35770
Ссылки в тексте:
[1] jack: http://jackaudio.org/
[2] PulseAudio: http://www.pulseaudio.org
[3] squeezebox: http://en.wikipedia.org/wiki/Squeezebox_(network_music_player)
[4] RTP multicast: http://www.videolan.org/doc/streaming-howto/en/ch04.html#id349956
[5] video on demand: http://www.videolan.org/doc/streaming-howto/en/ch05.html
[6] предпочтительным решением: http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/
[7] небольшой хак: http://yadi.sk/d/Uqp2eVBH5QmU1
[8] Источник: http://habrahabr.ru/post/181728/
Нажмите здесь для печати.