深入 PipeWire

news2025/4/9 8:32:19

简介

随着它的成熟,PipeWire 项目正在慢慢地变得流行。它的文档依然相对稀少,但正在逐渐增长。然而,让项目外部的人尝试用他们自己的语言来理解和解释它总是一个好主意,重申想法,从他们自己的角度来看待它。

在之前的一篇文章中,我讨论了 Unix 上的通用音频栈,并有一节提到了 PipeWire。不幸的是,因为当时我没有找到足够的文档,并且无法理解一些概念,我认为我没有对项目进行公正的处理,甚至可能混淆了某些部分。

在这篇文章中,我将尝试用可能的最简单的方式来解释 PipeWire,让那些想要追随这个很酷的新项目,但又不知道从哪里开始的人能够接触到它。尤其重要的是,这样做可以为更多的人打开一扇门,可以让他们加入并关注当前的发展,这正在快速进行。

免责声明:首先我想说的是,我并不是参与这个项目的开发者,只是一个感兴趣的互联网旅行者。我可能仍然犯了错误,没有涵盖所有内容,所以一定要留下评论或电子邮件,以便我可以纠正或添加信息。

PS:如果你喜欢深入研究和类似的讨论,那就去 nixers 社区看看,那里有很多喜欢这样做的人。

PPS:我在这篇文章中使用了一个与令人难以置信的 PulseAudio Under the Hood 一文类似的名字,但我不认为我能像 PulseAudio 的作者所做的那样详细介绍 PulseAudio。

什么是 PipeWire —— 快速试运行

PipeWire 是一个媒体处理图,这可能不太清晰,所以让我重新表述一下。PipeWire 是一个守护进程,它提供了类似于 shell 管道的东西,但是用于媒体:音频和视频。

在这个图中存放的是可以代表多种事物的节点,从耳机或网络摄像头等真实设备到音频过滤器等虚拟事物。这些节点具有端口,这些端口可以链接在一起,媒体数据从第一个节点的 source 流向下一个节点的 sink。每个节点中发生的事情取决于它们以及它们提供的接口或功能。

实际上,节点、链接、端口和其它都是扩展基本类型的不同对象,并且存在于此图中。这些对象也不一定是与媒体相关的,它们可以做很多其它的事情。我们将看到它们使用特殊的类型系统、插件系统和序列化格式/存储。

总而言之,PipeWire 是一个图,“它是机制而不是策略”。这意味着要创建图并与之交互,我们需要另一个软件。标准的方法是依赖 PipeWire 称为会话管理器或策略管理器的东西。这种软件的角色是依赖于环境创建并管理图中的实体,比如当设备插入时,或者设置了恢复音量策略,或者在允许一个客户端访问设备之前需要检查权限。

目前,有两个这样的会话管理器实现:默认的称为 pipewire-media-session,还有一个还在开发中,但非常有前途和有趣的,称为WirePlumber。而且,你可以选择依赖外部工具来管理 PipeWire 图中的内容来构建自己的会话管理工作流。

让我们到此为止,并看看如何运行 PipeWire。从你的包管理器获取它,并在终端中执行如下命令。

$ pipewire

在另一个终端中执行如下命令:

$ pipewire-media-session

在某些情况下,正如我们将在 pipewire 的配置中看到的,你可能不需要执行第二个命令,pipewire 可以被设置为自动启动 pipewire-media-session。事先试一试 ps 以防万一。

如果没有应用程序可以与 PipeWire 对话,那么上述操作也不会让你有所收获 —— 目前只有少数应用程序可以。此外,PipeWire GUI 和工具仍然缺乏,我们将看到。这也就是为什么 PipeWire 要提供三个兼容层:通过一个 PCM 设备与 ALSA 兼容,通过 pipewire-pulse 服务器与 PulseAudio 兼容,通过 pw-jack 命令与 JACK 兼容。

要确保你获得了 ALSA 的兼容性,请检查 /etc/alsa/conf.d/50-pipewire.conf 文件,它应该为 pipewire 定义了一个 pcm,它通常在安装 pipewire-alsa 包时创建。然后通过 alsactl dump-cfg 或 aconfdump 查看 ALSA 配置,来检查它是否已经变为了默认 pcm,并验证 pcm.default 项(通常通过 99-pipewire-default.conf 这样的东西)。然而,如果你仍然想要依赖 PulseAudio,它就不需要了,在这种情况下,它将是 type pulse

对于 PulseAudio 层,它允许使用 PulseAudio 工具来与 PipeWire 通信,安装 pipewire-pulse 并启动它。你的发行版甚至可能通过 init/service 管理器与会话管理器一起自动启动它。

最后,对于 JACK,安装 pipewire-jack 包并在任何 JACK 相关的命令之前发出 pw-jack,则它们将自动地使用 PipeWire。比如:

$ pw-jack qjackctl

此外,对于视频功能,你应该安装桌面 portal,它是一个实现了 xdg-desktop-portal 规范的 D-Bus 服务,它的工作是检查是否允许客户端请求访问视频。有许多这样的软件:

  • xdg-desktop-portal-gtk
  • xdg-desktop-portal-kde
  • xdg-desktop-portal-wlr

如果你正在运行 Wayland 合成器,你应该熟悉这些,因为这是在 Wayland 上访问视频 (网络摄像头,屏幕共享,截屏) 的唯一方法。

自此,PipeWire 运行起来了!然而,还有更多东西要看,比如如何配置 PipeWire 和会话管理器,如何编写依赖 PipeWire 的软件,其中蕴含的思想,如何管理图和依赖工具,以及大量其它示例。

与 GStreamer 的关系

构建块:POD/SPA

POD —— Plain Old Data

SPA —— Simple Plugin API

PipeWire Lib,来自 Wayland 的灵感

配置

PipeWire 服务器配置

PipeWire 客户端配置

PipeWire 会话管理器配置

PipeWire 媒体会话配置

WirePlumber 配置

工具 & 调试

本地 PipeWire 工具

PipeWire 带有一系列工具,可以用来执行常见的任务,如与服务器交互,调试或性能调优。如果你熟悉 PulseAudio 带的工具集,你将发现它们很相似。

下面是其中一些有趣的工具:

  • pw-cat:用于播放音频
  • pw-playpw-recordpw-midirecordpw-midiplay:指向 pw-cat 的符号链接
  • pw-record:用于录制音频
  • pw-loopback:创建虚拟环回节点
  • pw-link:端口和链接管理器,用于列出端口,监视它们,并创建链接
  • pw-dump:用于转储图中的节点或整个图
  • pw-dot:与 pw-dump 类似,但以 graphviz 格式转储
  • pw-toppw-profiler:用于监视图中对象之间的流量效率
  • pw-mon:用于监视图中发生的任何事件
  • pw-metadata:用于修改图中的元数据,它当前被用于存储默认的节点信息
  • pw-cli:与 PipeWire 守护进程交互的通用命令行工具,允许用来转储,加载和卸载模块,列出对象,创建链接和节点,设置参数,等等。

这些工具,特别是 pw-cli,可以被用来创建对象并管理运行中的图,或调查图中发生的事。

这里有一个在两个节点的两个左前端口间创建链接的例子:

$ pw-cli create-link "TestSink" 'monitor_FL' \
"alsa_output.usb-C-Media_Electronics_Inc.device.iec958-stereo" \
'playback_FL'

或者转储所有可用的工厂:

$ pw-cli dump Factory

或者创建一个虚拟节点:

pw-cli create-node adapter { \
factory.name=support.null-audio-sink node.name=my-mic \
media.class=Audio/Duplex object.linger=1 \
audio.position=FL,FR }

除了命令行工具之外,目前还存在一个名为 helvum 的基于 Rust-Gtk 的本地 GUI。它仍然是一个 WIP 项目,提供通过点击两个边的端口连接节点的基本功能。除此之外,PipeWire 还缺乏前端,特别是那些允许适当地操纵/表示任何类型媒体(包括音频和视频)的图的前端。

helvum 看起来像这样:请添加图片描述
更新:现在有一个新的 QT GUI 称为 qpwgraph)

我自己也尝试过用 Rust 构建一些东西,但是 Rust 绑定,特别是与 POD 和 SPA 相关的绑定,仍然是一个正在进行的工作。很难绑定到 rust,因为 PipeWire 库大多只有 static inline 函数。

然而,有一些有趣的工具,如 PulseEffects,允许创建过滤器节点来动态添加音频效果。

另一方面,当谈到会话管理器时,pipewire-media-session 目前还没有客户端,而 WirePlumber 确实提供了一组命令行工具。

我们已经看到 wpexec 执行 lua 脚本。还有 wpctl,它是另一个调查工具,用来询问 WirePlumber 关于可用的设备、节点、它们的属性和它们的音量的信息。它可用于与“端点”的概念进行交互,“端点”是会话管理器的媒体开始和结束位置的抽象表示。

wpctl status 可被用于列出已知的端点,其中默认的设备前面会展示一颗星字符。这个默认设备可以使用 set-default 选项传递节点 ID 来修改。其它选项,如 set-volumeset-muteset-profile 都很容易理解。

依赖于 PulseAudio 的工具

pipewire-pulse,正如我们所说的,是加载 libpipewire-module-protocol-pulse 模块的包装器,它允许在 PipeWire 兼容层之上使用大多数 PulseAudio 功能和软件。模块本身可以在 pipewire-pulse.conf 文件中通过一些选项配置,如 这里 所示。它甚至涵盖了网络协议支持的模块。

因此,它允许我们使用任何我们已经习惯使用于 PulseAudio 的用户接口,如 pavucontrol, pulsemixer, pamixer 等。这还包括命令行工具,如 pactl,它给了我们除 pw-cli 外的另一种与 PipeWire 交互的方式。

$ pactl info

Server String: /run/user/1000/pulse/native
Library Protocol Version: 34
Server Protocol Version: 35
Is Local: yes
Client Index: 106
Tile Size: 65472
User Name: vnm
Host Name: identity
Server Name: PulseAudio (on PipeWire 0.3.30)
Server Version: 14.0.0
Default Sample Specification: float32le 2ch 48000Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.pci-0000_00_14.2.analog-stereo
Default Source: alsa_input.pci-0000_00_14.2.analog-stereo
Cookie: daad:fd8f

虽然 pactl 应该与 PulseAudio 一起使用,但其功能在某种程度上映射到了 PipeWire。这包括模块的加载,这可被用于在图中创建节点。

pactl load-module module-null-sink object.linger=1 \
media.class=Audio/Sink \
sink_name=my-sink \
channel_map=surround-51

正如你可能注意到的,module-null-sink 的语法与你在 PulseAudio 中使用的语法完全不同。这相同的模块也可以被用于创建全双工或 source 节点。更多关于创建虚拟设备的信息请点击 这里。

映射甚至对于通过 pactl list modules 列出模块也能工作,只是列出的是 PipeWire 的模块。很明显,我们可以列出对象,或特定的东西,比如通过 pactl list sinks 列出 sinks。

这个有用的指南 显示了 PulseAudio 和 PipeWire 之间特性的映射,包括我们展示的 pactl 和特定于 PulseAudio 的某些配置。

下面是 pulsemixer 在 PipeWire 上运行的截图:
请添加图片描述

依赖于 Jack 的工具

正如 PulseAudio 一样,PipeWire 提供了一个 JACK 的兼容层。它是通过在 JACK 命令前加上 pw-jack 来启动的,例如:

$ pw-jack jack-plumbing
$ pw-jack qjackctl

NB:你可以在 这里 找到 jack-plumbing,这是一个创建 jack 规则连接规则的非常好的工具。

pw-jack 是一个 shell 脚本,它设置了一些环境变量,并修改了 LD_LIBRARY_PATH 以在全局的那个之前指向 PipeWire 的 jack lib。你可以通过以下操作注意到这一点:

pw-jack ldd /usr/bin/qjackctl| grep -i libjack

libjack.so.0 => /usr/lib/pipewire-0.3/jack/libjack.so.0 (0x00007f65c9fa0000)

与 PulseAudio 的类似,这允许我们使用大多数基于 JACK 的 GUI 工具,如 qjackctl,carla,catia,和所有漂亮的可视化工具。与 PulseAudio 工具相比,JACK 工具的优势在于,它已经默认显示了一个图,可以很好地映射到 PipeWire 的概念,但它只映射音频设备,而不映射视频设备。PipeWire 也允许在运行时修改图,效果是即时的,不像JACK,这是很棒。

文档还列出了与 JACK 有关的特有配置,通常位于 jack.conf

下面是 qjackctl 在 PipeWire 上运行的截图:

请添加图片描述

依赖于 GStreamer 的工具

最后,正如我们前面提到的,我们可以依赖使用 gstreamer 的任何程序和 gstreamer 命令行工具来处理媒体。再次,通过如下插件:

  • pipewiresrc:PipeWire source
  • pipewiresink:PipeWire sink
  • pipewiredeviceprovider:PipeWire Device Provider

我们可以创建一个 PipeWire sink,它将提供来自网络的音频:

gst-launch-1.0 \
uridecodebin 'uri=http://podcast.nixers.net/feed/download.php?filename=nixers-podcast-2020-07-221.mp3' ! \
pipewiresink mode=provide \
stream-properties="props,media.class=Audio/Source,node.description=podcast"

然后将端口链接到一个音频设备,通过命令行工具或 helvum 这样的 GUI。

pw-link gst-launch-1.0:capture_1 \
alsa_output.usb-C-Media_Electronics_Inc._Microsoft_LifeChat_LX-3000-00.iec958-stereo:playback_FL
pw-link gst-launch-1.0:capture_2 \
alsa_output.usb-C-Media_Electronics_Inc._Microsoft_LifeChat_LX-3000-00.iec958-stereo:playback_FR

理论上,这也应该允许我们管理视频,然而,正如我上面提到的,我遇到了一些问题。我已经测试了如下命令,并尝试通过 cheese 网络摄像头应用打开它,但视频只展示了 2s 就停止了:

gst-launch-1.0 \
uridecodebin uri=https://venam.net/workflow-compil-venam-2020.webm ! \
pipewiresink mode=provide \
stream-properties="props,media.class=Video/Source,node.description=compilation"

尽管如此,这种可能性还是很吸引人的:在运行中轻松地对视频(包括相机)进行修改和添加滤镜。

结论

原文。

Done.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2310074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

20250304笔记-阅读论文

文章目录 前言一、寻找论文1.1寻找有代码的论文方法一:浏览器扩展1.1.1使用流程 方法二:使用Papers with Code 1.2大量搜索代码 二、阅读论文所用软件 三、引用文献格式总结 前言 一、寻找论文 1.1寻找有代码的论文 方法一:浏览器扩展 浏览…

线程POSIX信号量/基于环形队列的⽣产消费模型

一,POSIX线程信号量 信号量的本质就是一个计数器,也是对资源的预定机制,POSIX信号量和SystemV信号量作⽤相同,都是⽤于同步操作,达到⽆冲突的访问共享资源⽬的。但 POSIX可以⽤于线程间同步。 1,初始化信…

C# 类库打包dll文件

目录 前言操作流程注意事项 前言 在C#中,有多种方式可以对代码进行加密,以保护源代码不被轻易查看或修改,这篇文章主要介绍将C# cs类文件加密为dll文件的方式进行保护。 操作流程 在 Visual Studio 中,选择“创建新项目”。 选…

DELL EMC Unity存储如何让控制器进入service mode和退出service mode

近期遇到好几个关于DELL EMC unity (VNXe)存储系统挂掉的案例,都是很后期才寻找支持到我们这里,然后再看问题,已经变得很复杂,几乎都是从一个相对简单的问题搞成了一锅粥甚至最后丢数据的情况。 为此&…

【微知】如何通过mlxlink查看Mellanox网卡和光模块相关的信息?( mlxlink -d 01:00.0 -m)

背景 通过mlxlink可以查看Mellanox网卡的一些链路信息和硬件信息,也可以查看所插入的光模块的一些信息。 兄弟篇通过ethtool查看的方法:如何查看Mellanox网卡上的光模块的信息? 命令 mlxlink -d 01:00.0 -mman手册介绍: 如果…

Linux系列:如何用 C#调用 C方法造成内存泄露

一个简单的非托管内存泄露 1. 构建 so 文件 在 Windows 平台上我们会通过 MSVC 编译器将 C代码编译出一个成品 .dll,在 Linux 上通常会借助 gcc 将 c 编译成 .so 文件,这个.so 全称 Shared Object,为了方便讲解,先上一段简单的代码…

C# 数据类型相关

分类 按照数据复杂程度 按照数据存储 类型转换 隐式转换 隐式转换无法完成由精度高的数据类型向精度低的数据类型转换 显式转换 又称为强制类型转换,显示转换不一定总是成功,且转换过程中可能出现数据丢失 int num 666;float result (float)num; …

使用Word时无法粘贴,弹出错误提示:运行时错误‘53‘:文件未找到:MathPage.WLL

报错说明 使用Word时无法粘贴,粘贴时弹出提示如下: 一般出现这种情况时,我想你是刚装完MathType不久,博主装的是MathType7版本,出现了这个问题。 出现这个问题的原因是"mathpage.wll"这个文件在Office的插…

玩转python: 深度解析Python高阶函数及推导式

1 高阶函数:工程化编程的基石 1.1 高阶函数基础概念 高阶函数(Higher-Order Function)是函数式编程范式的核心要素,指能够接受函数作为参数或返回函数作为结果的函数。在Python中,这类函数构成了数据处理的基础架构&…

Linux第五讲----gcc与g++,makefile/make

1.代码编译 1.1预处理 我们通过vim编辑完文件之后,想看一下运行结果这时我们便可以试用gcc编译C语言,g编译c. 编译代码: 上述两种方法均可,code.c是我的c语言文件,mycode是我给编译后产生的二进制文件起的名&#x…

ubuntu22.04下Meshlab打开obj文件闪退——使用Appimage并放入收藏夹中

文章目录 ubuntu22.04下Meshlab打开obj文件闪退,查了下是meshlab的apt没做好。 官网下载:https://www.meshlab.net/#download 赋予权限 sudo chmod a+x MeshLab2023.12-linux.AppImage 双击运行即可 打开权限——下面操作是放在桌面上的 创建桌面快捷方式 # 在 ~/desktop (…

MAVEN的环境配置

在下载好maven后或解压maven安装包后进行环境配置 1.在用户环境变量中 新建一个MAVEN_HOME 地址为MAVEN目录 注:地址为解压后maven文件的根目录!!! 2.在系统环境变量的path中添加该变量 %MAVEN_HOME%\bin 3. 测试maven安装是否成…

强化学习无痛上手笔记第1课

文章目录 Markov Decision ProcessDefinitionRelated Concepts Policy for MDP AgentDefinitionJudgement for PolicyValue FunctionsTD formula for value functionsRelation of V and QPolicy CriterionPolicy Improvement TheoremOptimal PolicyReinforcement Learning Fund…

智能设备上的 AI 移植与部署:新趋势与实践案例

1. 引言:智能设备如何运行 AI? 随着人工智能(AI)技术的快速发展,AI 计算已经从云端走向边缘,嵌入到智能设备中,如智能手机、智能摄像头、机器人、自动驾驶汽车等。这种本地化 AI 计算能够减少延…

【USRP】NVIDIA Sionna:用于 6G 物理层研究的开源库

目录 Sionna:用于 6G 物理层研究的开源库主要特点实现6G研究的民主化支持 5G、6G 等模块化、可扩展、可伸缩快速启动您的研究 好处原生人工智能支持综合研究平台开放生态系统 安装笔记使用 pip 安装基于Docker的安装从源代码安装“你好世界!”探索锡奥纳…

LLM大型语言模型(一)

1. 什么是 LLM? LLM(大型语言模型)是一种神经网络,专门用于理解、生成并对人类文本作出响应。这些模型是深度神经网络,通常训练于海量文本数据上,有时甚至覆盖了整个互联网的公开文本。 LLM 中的 “大” …

BUU44 [BJDCTF2020]ZJCTF,不过如此1 [php://filter][正则表达式get输入数据][捕获组反向引用][php中单双引号]

题目: 我仿佛见到了一位故人。。。也难怪,题目就是ZJCTF 按要求提交/?textdata://,I have a dream&filenext.php后: ......不太行,好像得用filephp://filter/convert.base64-encode/resourcenext.php 耶?那 f…

软考中级-数据库-3.3 数据结构-树

定义:树是n(n>=0)个结点的有限集合。当n=0时称为空树。在任一非空树中,有且仅有一个称为根的结点:其余结点可分为m(m>=0)个互不相交的有限集T1,T2,T3...,Tm…,其中每个集合又都是一棵树,并且称为根结点的子树。 树的相关概念 1、双亲、孩子和兄弟: 2、结点的度:一个结…

磁盘空间不足|如何安全清理以释放磁盘空间(开源+节流)

背景: 最近往数据库里存的东西有点多,磁盘不够用 查看磁盘使用情况 df -h /dev/sda5(根目录 /) 已使用 92% 咱们来开源节流 目录 背景: 一、开源 二、节流 1.查找 大于 500MB 的文件: 1. Snap 缓存…

SpringCloud系列教程(十二):网关配置动态路由

除了token以外,还有一个很实用的功能就是把网关的路由配置放到nacos上,并且修改路由配置的时候,网关服务可以动态的更新,这样我们在调整网络配置的时候,就不用重启服务了。所以我们需要用到两个重要的类:Na…