libpipew...l-native(7)

πŸ’– libpipew...l-native(7) πŸ’–

okay bestie, pull up a chair 🫢 this is libpipew...l-native(7), straight out of the Miscellaneous Information Manual, and it's the whole tea on the native protocol module. it's giving plumbing, but make it cute.


✨ NAME ✨

libpipewire-module-protocol-native β€” Protocol Native πŸ‘‘

🌸 DESCRIPTION 🌸

so this native protocol module is the one that makes PipeWire communication happen between a client and a server, using unix local sockets. no cap, that's literally its whole job πŸ’…

normally this module gets loaded in both the client and the server config files, so they can actually talk to each other. if it's not there, they're just two strangers in the group chat πŸ™ˆ

πŸŽ€ MODULE NAME πŸŽ€

libpipewire-module-protocol-native

πŸ¦‹ MODULE OPTIONS πŸ¦‹

the module supports these arguments, bestie:

  • sockets β€” an array of Unix socket names and (optionally) owner/permissions to serve, if the context is a server 🫢 the shape is:
sockets: [ { name = "socket-name", owner = "owner", group = "group",
  mode = "mode", selinux.context = "context" }, props = { ... }, ... ]

if the socket paths aren't absolute paths, the sockets get created in the default runtime directory ✨

the props get copied directly to any client that connects through this server socket, and they can be used to configure special permissions πŸ‘‘

it has the default value [ { name = "CORENAME" }, { name = "CORENAME-manager" } ], where CORENAME is the name of the PipeWire core, usually pipewire-0.

real talk though: the permissions have no effect for sockets that come from Systemd socket activation 😭 those ones need to be configured through the systemd.socket(5) mechanism instead. don't fight it, just do it that way.

🌈 GENERAL OPTIONS 🌈

the name of the core is obtained like this, in order:

  • PIPEWIRE_CORE : the environment variable with the name of the core
  • core.name : in the context properties
  • a name based on the process id

and the context will also become a server if:

  • PIPEWIRE_DAEMON : the environment is true
  • core.daemon : in the context properties is true

the socket will be located in the directory obtained by looking at these environment variables:

  • PIPEWIRE_RUNTIME_DIR
  • XDG_RUNTIME_DIR
  • USERPROFILE

the socket address will be written into the notification file descriptor if this environment variable is set:

  • PIPEWIRE_NOTIFICATION_FD

when a client connects, the connection will be made to:

  • PIPEWIRE_REMOTE : the environment with the remote name
  • remote.name : the property in the context.
  • the default remote named "pipewire-0"

a special remote named "internal" can be used to make a connection to the local context πŸ‘€ this is doable even when the server is not a daemon. it lets you treat a local context as if it was a server. main character energy tbh.

πŸ’œ CONFIG OVERRIDE πŸ’œ

a module.protocol-native.args config section can be added to override the module arguments. slay.

# ~/.config/pipewire/pipewire.conf.d/my-protocol-native-args.conf

module.protocol-native.args = {
       sockets = [
           { name = "pipewire-0" }
           { name = "pipewire-0-manager" }
       ]
}

⭐ EXAMPLE CONFIGURATION ⭐

context.modules = [
{ name = libpipewire-module-protocol-native }
]
context.modules = [
 { name = libpipewire-module-protocol-native,
   args = {
       sockets = [
           { name = "pipewire-0" }
           { name = "pipewire-0-manager" }
           { name = "pipewire-1"
             props = { my.connection = "the other one" }
           }
       ]
   }
 }
]

and that's the whole page, bestie, you ate that πŸ“ this was brought to you by PipeWire version 1.6.11 on the libpipew...l-native(7) page β€” go forth and let your sockets communicate fr fr πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from