WirePlumber: переключение профилей звука
Подключил HDMI-монитор, а звук остался в колонках — или наоборот, наушники есть, а в системе их нет. Почти всегда причина одна: у звуковой карты стоит не тот профиль, а менять его вручную неохота. PipeWire профили не выбирает, за него это делает WirePlumber, и весь разбор сводится к четырём понятиям — карта, профиль, узел и маршруты. Разложим их по полкам и разберём, что делать, когда переключение нужно довести до автоматического.
Чем карта отличается от профиля и узла?
Карта (device) — это ALSA-карта, то есть контейнер для путей. В wpctl status она видна как строка вроде 57. Renoir/Cezanne HDMI/DP Audio Controller [alsa]. Сама по себе карта звука не производит: у неё есть только список возможностей.
Профиль (profile) — набор этих возможностей: какие порты открыть и сколько sink/source из них получится. У типичной карты ноутбука в списке есть output:analog-stereo (только аналоговый выход), output:hdmi-stereo (только HDMI), объединённый output:analog-stereo + input:analog-stereo и универсальный pro-audio. Профиль решает, появится ли вообще sink для HDMI, поэтому смена профиля — главный ход при пропащем звуке.
Узел (node) — конкретный поток, созданный из профиля: sink для воспроизведения, source для записи. Имя узла заканчивается именем профиля, поэтому по нему видно, что сейчас стоит: alsa_output.pci-0000_30_00.6.analog-stereo — sink, alsa_input.pci-0000_30_00.6.analog-stereo — source (микрофон или линия). После смены профиля узлы пересоздаются и получают новые номера.
Маршруты (routes) — порты карты и правило, какой из них активен: analog-output-headphones, hdmi-output-0, analog-input-mic. Смена маршрута не трогает профиль и не меняет sink, но именно она решает, звук в разъёме или в HDMI.
Как посмотреть, что сейчас настроено?
Главная команда — wpctl status:
wpctl status
Audio
├─ Devices:
│ 57. Renoir/Cezanne HDMI/DP Audio Controller [alsa]
│ 58. Ryzen HD Audio Controller [alsa]
├─ Sinks:
│ * 34. Ryzen HD Audio Controller Аналоговый стерео [vol: 0.25]
│ 47. Renoir/Cezanne HDMI/DP Audio Controller Цифровой стерео (HDMI) [vol: 0.55]
├─ Sources:
│ 49. Ryzen HD Audio Controller Аналоговый стерео [vol: 1.00]
└─ Streams:
Звёздочка отмечает узел по умолчанию. Флаги -k и -n меняют вид: -k показывает короткие имена (node.nick, например ALC897 Analog), -n — технические node.name.
Список профилей с полными флагами удобнее смотреть через PulseAudio-совместимый вывод:
pactl list cards
В секции Profiles: у каждого профиля есть количество sink’ов и source’ов, приоритет и доступность. Там же видно текущий выбор строкой Active Profile: и секция Ports: с типами разъёмов.
Низкоуровневый вид — через PipeWire напрямую:
pw-cli list-objects Node | grep -E 'node.name|node.nick|media.class'
pw-dump > /tmp/pw.json
Отдельного флага --verbose у команды wireplumber нет: бинарь понимает только -v/--version, -c/--config-file и -p/--profile. Зато подробности есть у wpctl inspect <ID> (все свойства объекта) и у лога в реальном времени.
Как переключить профиль карты вручную?
Порядок такой. Сначала находим номер карты в wpctl status (у нас это 58). Потом смотрим индексы профилей — они есть и в pactl list cards, и в параметре EnumProfile карты. Дальше одна команда:
wpctl set-profile 58 2
Индексы всегда одни и те же для одной карты: 0 — off, дальше output:analog-stereo, output:hdmi-stereo и так далее по списку. Ноль означает «профиль выключено»: у этой карты пропадают все sink’и и source’и, звука нет вообще. Проверяем результат:
wpctl status
Тот же переключатель через PulseAudio-совместимый синтаксис, где профиль задаётся именем, а карта — строкой device.name (её видно в выводе wpctl inspect):
pactl get-card-profile alsa_card.pci-0000_00_1f.3
pactl set-card-profile alsa_card.pci-0000_00_1f.3 output:hdmi-stereo
Помни про две мелочи. Первая: после смены профиля номера узлов меняются, поэтому дефолтный sink лучше задать заново — wpctl set-default 47. Вторая: выбор профиля хранится в состоянии WirePlumber и переживает перезапуск, но сбрасывается, если правило выбора не совпадает с тем, что ты сделал руками.
Как заставить WirePlumber всегда ставить нужный профиль?
Ручной выбор — это разовое действие. Для постоянства нужен конфиг: WirePlumber 0.5 читает файлы из /etc/wireplumber/wireplumber.conf.d/ и из ~/.config/wireplumber/wireplumber.conf.d/, в формате SPA-JSON, где комментарии начинаются с #. Создай /etc/wireplumber/wireplumber.conf.d/50-card-profile.conf:
# принудительный профиль для карты по короткому имени ALSA
monitor.alsa.rules = [
{
matches = [
{ alsa.card_name = "HD-Audio Generic" }
]
actions = {
update-props = {
device.profile = "pro-audio"
}
}
}
]
Как это работает: скрипт device/find-best-profile смотрит свойство device.profile у карты, и если профиль с таким именем доступен, он получает абсолютный приоритет над всеми остальными кандидатами. Отсюда и available в списке профилей: значение no отбрасывает профиль, unknown (как у pro-audio на большинстве карт) оставляет на волю правилу, yes — пригоден для автоматического выбора.
Имя для matches берётся из свойств карты, а не из догадок:
wpctl inspect 58 | grep -E 'card_name|device.name'
cat /proc/asound/card0/id
Кроме alsa.card_name можно матчить device.name (alsa_card.pci-0000_00_1f.3), node.name или node.nick. Более тонкий вариант — секция device.profile.priority.rules, где перечисляются имена профилей в порядке предпочтения: выигрывает первый доступный, и если его нет, берётся следующий.
Применяем и проверяем:
sudo mkdir -p /etc/wireplumber/wireplumber.conf.d
systemctl --user restart wireplumber
wpctl status
Если параллельно живёт PulseAudio, он умеет перехватывать карту и ставить профиль по-своему — про конфликт и его разбор я писал здесь. Правило не сработало — смотри лог: journalctl --user -u wireplumber -f, там видно, какой профиль выбрал менеджер и почему отказался.
Как устроено автопереключение в 0.5?
Логика выбора в WirePlumber 0.5 разложена по Lua-скриптам, объявленным как виртуальные возможности policy.*. За профили отвечает policy.device.profile (это device/select-profile.lua, device/find-best-profile.lua, device/apply-profile.lua и автопереключение Bluetooth-профиля), за узлы по умолчанию — policy.default-nodes (default-nodes/find-best-default-node.lua, state-default-nodes.lua, apply-default-node.lua), за маршруты — policy.device.routes, за соединение потоков — policy.linking.standard.
Порядок выбора профиля в таком случае такой: голосовой вызов, потом твои правила, потом сохранённый ранее профиль, потом «лучший» по приоритету среди доступных. Отсюда два полезных выключателя, которые правятся в .conf-файле:
wireplumber.settings = {
device.restore-profile = false
node.restore-default-targets = false
}
Первый запрещает запоминать выбор и возвращать его при старте, второй — запоминать, какой узел был дефолтным, иначе WirePlumber продолжает цепляться за устройство, которого уже нет.
Источники живут по тем же правилам: source — это узел с классом Audio/Source, у наушников с микрофоном он появляется вместе с профилем гарнитуры, а переключение на него удобнее делать в pavucontrol, GNOME «Звук» или qpwgraph. Как выглядит перебор доступных вариантов в интерфейсе, я разбирал в статье про переключение на наушники. Отдельно в настройках есть bluetooth.autoswitch-to-headset-profile — он включён по умолчанию и заставляет Bluetooth-гарнитуру отдавать профиль с микрофоном во время записи.
Что такое routes и когда нужен профиль pro-audio?
Маршруты — это порты карты с указанием, доступны они сейчас или нет. В pactl list cards это секция Ports:, где у каждого порта есть тип (hdmi, headphone, mic), приоритет, группа доступности и пометка available или not available. У HDMI-карты порт hdmi-output-0 относится к группе Legacy 1, а hdmi-output-1 к Legacy 2 и числится недоступным, пока к нему ничего не подключено. Переключение маршрута не меняет профиль — проще всего сделать его мышкой в qpwgraph, из командной строки отдельной команды wpctl для портов нет, только Lua-скрипты. В настройках есть device.restore-routes — запоминать маршруты между сессиями, и device.routes.mute-on-alsa-playback-removed — заглушать звук при отключении кабеля.
pro-audio стоит выдельно. Он открывает все каналы напрямую, минуя микшер PulseAudio, и карта отдаёт их как есть. Нужен он для JACK, гитары, многоканального выхода, работы с внешним ЦАПом. Обычному пользователю не нужен: в списке профилей у него приоритет 1 и доступность unknown, поэтому автоматический выбор его пропускает, и включить его нужно руками или правилом из предыдущего раздела. Цена решения простая: приложения, ожидающие привычный стерео-микшер, получают один многоканальный sink, а громкость приходится крутить самой картой, потому что программного микшера над потоком нет.
Почему после смены профиля звук пропал?
Три причины закрывают почти все случаи. Первая: профиль в списке есть, но все его порты помечены available: no — путь через ALSA/UCM не открывается, и PipeWire не создаёт рабочий sink. Вторая: выставлен индекс 0, то есть профиль off, у которого ноль sink’ов и ноль source’ов, — карта включена, но играть нечем. Третья: дефолтный узел указывал на номер узла, которого после смены профиля уже не существует, поэтому звук идёт, но не туда.
Диагностика идёт снизу вверх:
wpctl inspect 57
pactl list sinks short
pw-dump | python3 -m json.tool | less
journalctl --user -u wireplumber -f
wpctl inspect карты покажет device.routes и доступность профилей, а wpctl inspect sink’а — device.profile.name и card.profile.device, то есть сразу станет ясно, какой профиль в силе. pactl list sinks short даёт состояние узла: RUNNING означает, что поток идёт, SUSPENDED — узел есть, но молчит. Если звук не появляется вообще ни в одном приложении, проверь сначала профиль и только потом микшер: разбор полностью молчащей системы начинается ровно с wpctl status.
Частые вопросы
Профиль сбросился после перезагрузки, что делать?
Убедись, что в /etc/wireplumber/wireplumber.conf.d/ нет файла с device.profile, который указывает на другое имя, и перезапусти systemctl --user restart wireplumber. Помогает очистка состояния: rm -r ~/.local/state/wireplumber при остановленном сервисе.
Можно ли переключить профиль, не перезапуская плеер?
Обычно да: WirePlumber переподключает активные потоки на новый узел, этому отвечает настройка linking.follow-default-target. С pro-audio так не выйдет — структура потока меняется, и аудиоплеер придётся перезапустить.
Почему wpctl set-profile не находит карту?
Номера карт не постоянны: между сессиями они меняются. Узнай номер заново через wpctl status или обойди нумерацию, взяв имя карты из pactl list cards и вызвав pactl set-card-profile.
Как отличить профиль от узла в выводе?
Профиль — строка со sinks:/sources: в секции Profiles:, возможности карты. Узел — строка в Sinks:/Sources: с номером и громкостью, конкретный поток, который уже можно выбрать через wpctl set-default.
Полезные ресурсы
- ArchWiki: WirePlumber — правила в конфигах, приоритеты узлов, отключение лишних карт.
- ArchWiki: PipeWire — виртуальные устройства, одновременный вывод, разбор профилей.
Заключение
Переключение профиля — это правка одной строки состояния: сначала смотришь wpctl status, потом узнаёшь индекс из pactl list cards и меняешь профиль через wpctl set-profile. Если менять приходится после каждого подключения монитора или наушников, переноси решение в конфиг с device.profile, и карта перестанет удивлять. А дальше остаётся смотреть wpctl inspect и лог — там видно всё, что надумал менеджер.
Не получилось? Поможем настроить
Задай вопрос в чате — отвечаем быстро, по делу и без воды.

Комментарии