https://pipewire.pages.freedesktop.org/wireplumber/index.html

WirePlumberの入門ドキュメントがまったくといってほど無い。公式ドキュメントはAPIリファレンスのような説明に終始しており、それをどう組み合わせて利用すればいいのかの解説が無い。知識ゼロで読むとマジで迷子になる。

PipeWireの責任はノードを管理するところまでで、ノードの入出力の接続管理はWirePlumberが担っている。

グラフを挿入。ノードはPipeWireの責任、エッジの作成がWirePlumberの責任

WirePlumberを理解するための最重要ポイント

/usr/share/wireplumber/wireplumber.confが実質のエントリーポイントなので、ここを起点に追いかければWirePlumberがなにをしているのか理解できる。公式ドキュメントから読み始めると個別概念の説明に終始しており、その関係性や全体像が見えてこない。

設定カスタマイズの最初の一歩

  1. WirePlumberはコンポーネントのコレクションである。コンポーネントはsystemd unitのように依存関係が設定されている。特に重要なのがLuaで書かれたスクリプトコンポーネントで、これを自分で書いて登録することでカスタマイズができる。
# ~/.config/wireplumber/wireplumber.conf.d/99-custom.conf
  {
    # コンポーネントの実装ファイル
    name = custom.lua,
    type = script/lua
    # どっちかというとこっちがコンポーネント名で依存関係やプロファイルで使う
    provides = my-custom
    requires = [ support.export-core ]
  }
  1. プロファイルという概念があり、アクティブなプロファイルに宣言されているコンポーネントがアクティブになる。とりあえずmainプロファイルでカスタムコンポーネントを有効にするところから始めると良い。
# ~/.config/wireplumber/wireplumber.conf.d/99-custom.conf
  main = {
    my-custom = required
  }
  1. スクリプトはLuaで書く。標準スクリプトを参考にしつつ、ここで初めて公式ドキュメントを読めばいい。もちろんPipeWireの知識は前提となっている。
-- ~/.local/share/wireplumber/scripts/custom.lua
-- custom script
Log:info("hello world")
  1. systemctl --user restart wireplumberで設定を反映する。

この手順が解説されていない(それぞれのステップが別々のページで説明されているが)のが罠すぎて相当迷った。

ちょっと自分の理解をまとめておく

WirePlumberはモジュラーで柔軟なルーティング管理コアであり、それ自体は特定のユースケースを提供しない。例えば「Bluetoothイヤホンの接続を検知したらデスクトップの音声をそこからも出力する」というユースケースを実装するためのAPIは提供しているが、このユースケースそのものは提供していない。 そのようなユースケースを実装してるのが/usr/share/wireplumberの標準設定ファイルとスクリプトである。例えば「新しい出力ノードが作成されたときにどの入力ノードへ接続するべきか」というロジックがここで実装されている。 つまり、コア+標準設定がセットになってはじめてLinux標準のメディアルーターとして機能する。なお、コアのドキュメントはあるが、標準設定がどういうポリシーで実装されているか、その解説が公式にないのでコードを読むしかない。例えばscripts/linking/にノード接続ロジックが書いてあったりする。GStreamerでpipewiresrc node.target-object=gamescopeパイプラインを起動したとき、「ノードのtarget-objectプロパティで設定されいるノードを探し、なければデフォルトノードに接続する」というようなロジックが書かれている。