Привет, Хабр!
Сегодня рассмотрим консольные утилиты 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. Перед началом можно пройти небольшое тестирование — оно поможет проверить ваши текущие знания и навыки.
А тем, кто настроен на серьезное обучение, крайне рекомендуем рассмотреть Подписку — выбираете курсы под свои задачи, экономите на обучении, получаете профессиональный рост. Узнать подробнее