Привет, Хабр!

Сегодня рассмотрим консольные утилиты PipeWire: pw-cli, pw-top, pw-metadata и сопутствующие инструменты.

Для начала напомню, что PipeWire — это мультимедийный сервер низкого уровня, способный обрабатывать и аудио, и видео‑потоки с минимальной задержкой. Он заменяет и PulseAudio, и JACK, действуя как ядро мультимедиа‑пайплайна. Механизм распределения потоков (routing) отделён от политики: PipeWire занимается неким «трубопроводом», а где соединять и какой девайс использовать — за WirePlumber или другим менеджером сессий.

Интерактивный pw-cli

Первая и главная утилита для низкоуровневой отладки — pw-cli. Без аргументов она запустит интерактивную сессию к PipeWire (обычно это pipewire-0). Видим приглашение в shell«e с именем инстанса. Здесь можно выполнять команды вроде в обычной консоли:

$ pw-cli
pw-cli(pipewire-0)> help

Команда list-objects (или просто ls) выведет все глобальные объекты сервера.

Например, можем найти ID нашего микрофона или звуковой карты:

pw-cli(pipewire-0)> ls
# Вывод: список объектов (Devices, Nodes, Links, Modules...)

Когда найдём нужный ID (скажем, 42), командой info 42 получите подробный список его свойств. Это аналог pactl list или wpctl inspect. Здесь видно тип объекта (Device/Node), factory‑name (например alsa_source или alsa_sink), состояние, профиль и т. д. Примерно так:

pw-cli(pipewire-0)> info 42
# info id 42
#   type: "PipeWire:Interface:Node" version: 29
#   info:
#    node.name = alsa_input.usb-Logitech...
#    node.description = Logitech USB...
#    params:
#     "Props": {"device.description":"Logitech...",
#               "node.name":"alsa_input.usb...",
#               "media.class":"Audio/Source",
#               ...}

По строкам видим, что объект 42 — это наш alsa_input с названием «Logitech USB Microphone». По названию легче понять, что в системе за что отвечает. Можно копировать нужный node.name или device.name для дальнейших команд.

Для автоматизации скриптов pw-cli можно запускать с ключом‑командой напрямую. Например, pw-cli ls выведет объекты и сразу выйдет. Можно также подключаться к удалённым инстансам (если они есть) через connect <remote-name>, но в обычном десктопе чаще пользуемся локальным.

Хороша и команда create-link: она соединяет два порта двух узлов (Nodes) в PipeWire‑графе. Синтаксис простой: pw-cli create-link <nodeA> <portA> <nodeB> <portB>. Порты, повторюсь, можно узнать через info. Например, если у нас Node 42 с портом 0 (микрофон) и Node 53 с портом 1 (какой‑нибудь виртуальный вход), то так связываем их:

pw-cli(pipewire-0)> create-link 42 0 53 1
# Создан линк, например id=100, он соединит выход 42:0 с входом 53:1

Эта команда эквивалентна ручному «провода» между двумя портами (подобно Jack/QJackCtl). Можно заменять ID на - или * для автоматического поиска портов, но мы чаще явно указываем нужные. После создания линка поток аудио сразу пойдёт от A к B. А чтобы убрать линк, есть destroy <link-id>или в pw-link можно -d.

По сути, pw-cli — мощная консольная оболочка (shell) для PipeWire. У неё есть еще много команд — например, load-module и unload-module для SPA‑модулей, enum-params/set-param для настройки параметров узлов (латентности и т. д.) Но мы сосредоточимся на том, что поможет стримеру: листинге объектов и связывании.

Мониторинг в реальном времени с pw-top

Иногда нужно узнать, насколько загружен аудио‑пайплайн. Для этого есть pw-top — аналог top для PipeWire. Запускаешь pw-top в терминале:

$ pw-top

Он выведет таблицу, где сверху — драйверы (active nodes, например ALSA‑карты), а под ними «подчинённые» узлы (Streams, Followers). Видим столбцы: S (статус узла: RUNNING/IDLE/SUSPENDED), ID, QUANT (количество семплов за цикл), RATE (частота дискретизации), WAIT, BUSY, W/Q, B/Q, ERR (количество xrun) и FORMAT, NAME.

Например:

S ID QUANT RATE WAIT  BUSY W/Q B/Q ERR FORMAT              NAME
+  1 1024 48000  0.2ms 0.3ms 0.02 0.03 0  s16le 2ch 48000Hz  alsa_output.pci-0000_00...
R  2    0  48000  0.0ms 0.0ms 0.00 0.00 0  s16le 2ch 48000Hz  alsa_input.usb-046d-Logitech...

Статус R означает узел запущен (running), S — приостановлен (suspended), I — idle. В колонках W/Q и B/Q видим загрузку DSP (процессора) и задержку. А столбец ERR показывает xruns — если там >0, значит были пропуски звука. Если лагает звук, зажмите в pw‑top c — это сбросит счётчики, и можно с чистого листа смотреть.

Можно также запускать pw-top в batch‑режиме (через --batch-mode --iterations=<N>) для логирования, но в интерактиве всё наглядно. Этот инструмент полезен для поиска проблем с производительностью: если загрузка постоянно близка к 100% или часто появляются xruns, значит, пора копать глубже в настройки буферов/кванта. Мы возвращаемся к настройкам через pw-metadata или WirePlumber, но об этом позже.

Настройка через pw-metadata

Иногда нужно подкрутить внутренние настройки PipeWire без правки файлов конфигурации. Для этого есть pw-metadata. Это не управляет аудио‑метаданными (как теги песен), а служит для задания встроенных параметров серверу. Можно посмотреть и поменять ключ/значение для объектов.

Например, существует специальный metadata‑объект settings (ID 0 по умолчанию в default пространстве), где хранятся параметры вроде кванта и семплов. Команда pw-metadata -n settings 0 выведет все текущие значения. Поменять их можно так:

# установим фиксированный квант 1024 вместо рекомендованного
pw-metadata -n settings 0 clock.quantum 1024

После этого PipeWire будет использовать квант 1024 для таймера, что иногда улучшает совместимость с некоторым железом. Аналогично можно делать clock.force-quantum, clock.force-periods и др. Если нужен откат, просто удалите запись:

pw-metadata -d 0 clock.quantum

Вообще pw-metadata мало где применяется, но полезно знать: он работает глобально и безопасно — метаданные удалятся сами при рестарте процесса. Главное — не путать с WirePlumber конфигами.

Поиск и отладка устройств

Что делать, если после подвешивания или переключения гарнитуры звуковое устройство «пропало» или «залетело» на нужный канал? Главная рекомендация — отслеживать события PipeWire в реальном времени. Для этого есть pw-mon (монитор) и команда wpctl status, но клинику мы проводим через pw-cli и pw-mon.

К примеру, pw-mon можно запустить и фильтровать по ключевым словам:

$ pw-mon | grep -E "(Device|added|removed)"

Каждый раз, когда система найдет или потеряет устройство (будет добавлен или удалён PipeWire:Device), вы увидите сообщение. Это позволяет ловить «плавающие» устройства — например, USB‑микрофон, который на пробуждении подвисает. Команда выглядит так:

pw‑mon | grep ‑E ”(Device|added|removed)”

Она выведет «added: AlsanCard…» или «removed:…» и поможет понять, что именно сгорело. Ещё можно запустить просто wpctl status (или pw-cli list-objects | grep Device), чтобы увидеть текущие девайсы и их ID.

Если устройство лежит в неподходящем профиле, поможет pw-cli или wpctl. Например, если HDMI переключилось на непонятные каналы, можно вручную пересоздать ссылку в PipeWire или заново загрузить устройство. Часто достаточно перезапустить модуль ALSA (через load-module/unload-module в pw-cli), но проще — рестартить pipewire:

$ systemctl --user restart pipewire wireplumber

Проблема после сна широко известна: PipeWire иногда не видит док‑станцию или гарнитуру из‑за «зависших» дескрипторов. Логи могут содержать строчки вида 'playback open failed: Device or resource busy'. Выход простой: автоматически перезагружать сервис после пробуждения. Для этого сделаем юзерский systemd‑сервис:

# ~/.config/systemd/user/restart-pw.service
[Unit]
Description=Restart PipeWire after resume
After=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user restart pipewire

[Install]
WantedBy=sleep.target

После этого systemctl --user enable restart-pw.service — и при пробуждении PipeWire перезапустится, возвращая звук к жизни. (Аналогичный трюк можно сделать через WirePlumber скрипты или dbus‑monitor, но systemd проще.)

Маршрутизация звука для стримера (Zoom & OBS)

Допустим, мы стримим в OBS, но параллельно с разговором в Zoom хотим поделиться своим звуком. Это значит, надо раздать аудиопоток в два потребителя. PipeWire позволяет напрямую соединять выходы и входы. Например, OBS имеет «Monitor»‑выход (порты monitor_FL/monitor_FR на виртуальном устройстве OBS), а Zoom ждёт вход (обычно устройство «Microphone»). Чтобы связать их, можно использовать pw-link (утилита‑сокращение для create‑link). Сначала посмотрим доступные порты:

$ pw-link -o -l    # -o: только выходы, -l: показать ID

В списке найдём что‑то вроде:

Output ports (ID):
  42: OBS:monitor_FL
  43: OBS:monitor_FR

И входы Zoom:

$ pw-link -i -l
Input ports (ID):
  101: Zoom:mic_input

Теперь создаём связь:

$ pw-link 42 101
$ pw-link 43 101

Этим мы «провели провода» из OBS (левый/правый монитор) в вход Zoom. Аналогично можно подключать микрофон к OBS: pw-link mic_out_id obs_in_id. Проще всего брать имена port‑ов, но можно и ID, если знаем точные. Пример связывания:

pw-link paplay:output_FL alsa_output.pci-0000_00...:playback_FL — linking specified output port to input port

Плюс можно использовать пассивные (неактивирующие) линк‑ы с ключом -P, например, чтобы оба устройства спали, когда нет активного аудио.

Если вы предпочитаете GUI, то есть приложение qjackctl: его граф можно использовать как «паяльную плату» Но в терминале всё делается pw-link или pw-cli create-link (они эквивалентны). Кстати, можно протянуть «провода» между портами OBS и Zoom, это стандартное решение. Наш вариант на bash выглядит примерно так:

# Задаём портовые алиасы (пример)
OBS_L=$(pw-link -I "OBS:monitor_FL")
OBS_R=$(pw-link -I "OBS:monitor_FR")
ZOOM=$(pw-link -I "Zoom:mic_input")

# Соединяем
pw-link $OBS_L $ZOOM
pw-link $OBS_R $ZOOM

Теперь Zoom будет слышать всё из OBS. Если же нужно противоположное (например, микрофон в OBS и Zoom одновременно), создаём две связи: микрофон→Zoom и микрофон→OBS. Стримерам важно уметь так вручную собирать топологию — GUI иногда сбоит, а CLI‑линки всегда показывают результат.

Общие советы и выводы

Используя pw-cli, pw-top и pw-metadata, мы получаем очень гибкую среду отладки «вживую». Например, если звук не идёт в то приложение, куда нужно, используем процедуру из гайда: сначала wpctl status, смотрим текущие устройства, затем pw-mon или pw-dump, и, наконец, ручное связывание через pw-cli. Если звук «пропадает» после сна — прописываем systemd‑сервис на рестарт (как выше). Метаданные (pw-metadata) помогут настройке квантов и буферов, а pw-top покажет, нет ли перегрузки DSP.

Всегда помните: PipeWire — это граф потоков. Каждый источник, каждый выход и коннектор — отдельный узел или порт.


Итак, мы увидели, что PipeWire предоставляет мощные инструменты для работы с мультимедийным стеком Linux прямо из терминала. Разобравшись с pw‑cli, pw‑top и pw‑metadata, становится понятно: уверенное владение консольными утилитами — это базовый навык для администратора Linux.

Если вы хотите системно прокачать такие умения, обратите внимание на курс Administrator Linux. Basic. Перед началом можно пройти небольшое тестирование — оно поможет проверить ваши текущие знания и навыки.

А тем, кто настроен на серьезное обучение, крайне рекомендуем рассмотреть Подписку — выбираете курсы под свои задачи, экономите на обучении, получаете профессиональный рост. Узнать подробнее

Комментарии (0)