当前位置: 首页 > news >正文

PipeWire 音频设计与实现分析一——介绍

PipeWire 是一个基于图的媒体处理引擎,一个可以运行多媒体节点图的媒体服务器,是 Linux 的音频/视频总线,它管理 Linux 系统中,不同应用程序对音频和视频设备的共享访问。它提供了一个本地客户端音频 API,但也提供兼容层来支持使用常见的音频 API,包括 ALSA、PulseAudio 和 JACK。

在实现上,PipeWire 主要分为几部分:

  • PipeWire 主守护进程 pipewire
  • PipeWire 的本地 API 客户端库
  • PipeWire 的 PulseAudio 兼容层,主要是 pipewire-pulse 守护进程
  • PipeWire 的 JACK 兼容层,主要是一个 shell 脚本和几个 JACK 兼容客户端库
  • PipeWire 的 ALSA 兼容层,主要是 PipeWire 的 ALSA 插件
  • PipeWire 的媒体会话管理器,目前主要有两个实现,一个是 pipewire-media-session,另一个是 wireplumber

PipeWire 在媒体节点图的处理方面,采用机制与策略分离的设计。PipeWire 主守护进程运行媒体节点图,是机制而不是策略。外部媒体会话管理器构建它们自己的音视频流水线,然后让 pipewire 守护进程执行最终的结果。这包括监听系统中设备状态的变化,并根据需要改变音视频流水线。

媒体会话管理器不属于 pipewire 项目本身,它们是单独的项目,独立的应用程序,它们通过 pipewire 的本地客户端 API 库与 PipeWire 主守护进程通信。媒体会话管理器目前的两个实现中,pipewire-media-session 的源码位于 media-session,WirePlumber 的源码位于 wireplumber,在 GitHub 上有 wireplumber 项目的镜像。PipeWire 社区有逐渐将媒体会话管理器从 pipewire-media-session 切换到 WirePlumber 的趋势,pipewire-media-session 的代码已经很少更新 (2025-03-09),甚至没有做 GitHub 的镜像。PipeWire 相关各部分结构如下图:
PipeWire Architecture Overall
PipeWire 中,大部分功能通过模块和插件实现,主守护进程 pipewire 和它的 PulseAudio 兼容层 pipewire-pulse 尽管运行在不同的进程中,但共用相同的可执行文件,这两个守护进程通过加载不同的配置文件,进而加载不同的模块和插件,来运行不同的逻辑,执行不同的功能,如:

$ ls -al /usr/bin/pipewire-pulse 
lrwxrwxrwx 1 root root 8 11月  9  2022 /usr/bin/pipewire-pulse -> pipewire

在 Ubuntu 操作系统平台上,pipewire 守护进程的配置文件为 /usr/share/pipewire/pipewire.conf,pipewire-pulse 的配置文件为 /usr/share/pipewire/pipewire-pulse.conf。媒体会话管理器同样有它的配置文件,pipewire-media-session 的配置文件为 /usr/share/pipewire/media-session.d/media-session.conf,此外,它还有用于监视 ALSA 音频设备、蓝牙音频设备和 V4L2 视频设备的配置文件 /usr/share/pipewire/media-session.d/alsa-monitor.conf/usr/share/pipewire/media-session.d/bluez-monitor.conf/usr/share/pipewire/media-session.d/v4l2-monitor.conf

本文分析应用程序接入 PulseAudio 本地 API 客户端库或 PipeWire 本地 API 客户端库的场景下,PipeWire 音频部分的设计和实现,这主要包括 PipeWire 的本地 API 客户端库、PipeWire 主守护进程 pipewire、PipeWire 的 PulseAudio 兼容层 pipewire-pulse 和媒体会话管理器 pipewire-media-sessionpipewire-media-session 主要与比较老的 pipewire 版本一起使用,尽管它有逐渐被替代的趋势,但它的实现逻辑更容易理解一点,这里仍然以它为例,来看 PipeWire 的会话管理器的实现。

代码获取及编译调试运行

安装 PipeWire 的首选方法是通过 Linux 系统发行版的包管理系统,比如通过 apt/dpkg 为 Debian/Ubuntu 等系统安装,通过 yum/rpm 为 Fedora/CentOS 等系统安装,然而,我们为了方便代码分析调试,从代码编译运行。

获取代码的方法有多种,从 pipewire 和 pipewire-media-session 的源码仓库,自然可以通过 git 命令获得源码。

如果是 Ubuntu 系统,可以通过 apt 命令获得源码,具体方法如下:

  1. 编辑 /etc/apt/sources.list 文件,取消注释那些 deb src 行,随后执行 sudo apt-get update 命令更新包仓库信息。
  2. 执行 sudo apt build-dep pipewiresudo apt build-dep pipewire-media-session 命令分别安装编译 pipewire 和 pipewire-media-session 所需的所有依赖包。
  3. 执行 apt source pipewireapt source pipewire-media-session 命令分别获得 pipewire 和 pipewire-media-session 的源码及其 debian 编译配置文件。
  4. 执行 cd pipewire-0.3.48 && dpkg-buildpackage -b -uc -nc 命令以 dpkg-buildpackage 的方式编译 pipewire 的源码,这将生成多个 .deb 文件。可以以同样的方式编译 pipewire-media-session 的源码。其中 dpkg-buildpackage-nc 参数表示不清理之前编译结果 (或者 --no-clean)。

dpkg-buildpackage 构建工具,封装 pipewire 本身的构建工具,编译生成正式版的 deb 包。对于调试分析,更方便的是,直接使用 pipewire 本身的构建工具编译生成 debug 版的二进制文件。PipeWire 使用称为 Meson 的构建工具作为它的构建过程的基础。这个工具与 Autotools 和 CMake 有点像。Meson 生成构建配置文件,喂给更底层的构建工具 Ninja,后者大概与我们更熟悉的 GNU Make 工作在相同的抽象层次上。

Meson 使用一个用户指定的构建目录,Meson 生成的所有文件都会放在这个目录中。本文中,构建目录称为 builddir

对于构建依赖,可以通过各个发行版的包管理工具安装。切换到 PipeWire 源码目录,并为 Ninja 生成构建配置文件:

$ cd pipewire-0.3.48
$ meson setup builddir

上面的命令完成之后,可以看一下配置的构建选项:

$ meson configure builddir 
Core properties:Source dir /media/data/develop/pipewire_0.3.48/pipewire-0.3.48Build dir  /media/data/develop/pipewire_0.3.48/pipewire-0.3.48/builddirMain project options:Core options                        Current Value                         Possible Values                       Description------------                        -------------                         ---------------                       -----------auto_features                       auto                                  [enabled, disabled, auto]             Override value of all 'auto' featuresbackend                             ninja                                 [ninja, vs, vs2010, vs2012, vs2013,   Backend to usevs2015, vs2017, vs2019,               vs2022, xcode]                       buildtype                           debugoptimized                        [plain, debug, debugoptimized,        Build type to userelease, minsize, custom]             cmake_prefix_path                   []                                                                          List of additional prefixes for cmake to searchdebug                               true                                  [true, false]                         Debugdefault_library                     shared                                [shared, static, both]                Default library typeforce_fallback_for                  []                                                                          Force fallback for those subprojectsinstall_umask                       0022                                  [preserve, 0000-0777]                 Default umask to apply on permissions of installed fileslayout                              mirror                                [mirror, flat]                        Build directory layoutoptimization                        2                                     [0, g, 1, 2, 3, s]                    Optimization levelpkg_config_path                     []                                                                          List of additional paths for pkg-config to searchstrip                               false                                 [true, false]                         Strip targets on installunity                               off                                   [on, off, subprojects]                Unity buildunity_size                          4                                     >=2                                   Unity block sizewarning_level                       3                                     [0, 1, 2, 3]                          Compiler warning level to usewerror                              false                                 [true, false]                         Treat warnings as errorswrap_mode                           default                               [default, nofallback, nodownload,     Wrap modeforcefallback, nopromote]             Backend options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------backend_max_links                   0                                     >=0                                   Maximum number of linker processes to run or 0 for no limitBase options                        Current Value                         Possible Values                       Description------------                        -------------                         ---------------                       -----------b_asneeded                          true                                  [true, false]                         Use -Wl,--as-needed when linkingb_colorout                          always                                [auto, always, never]                 Use colored outputb_coverage                          false                                 [true, false]                         Enable coverage tracking.b_lto                               false                                 [true, false]                         Use link time optimizationb_lto_threads                       0                                                                           Use multiple threads for Link Time Optimizationb_lundef                            true                                  [true, false]                         Use -Wl,--no-undefined when linkingb_ndebug                            false                                 [true, false, if-release]             Disable assertsb_pch                               true                                  [true, false]                         Use precompiled headersb_pgo                               off                                   [off, generate, use]                  Use profile guided optimizationb_pie                               true                                  [true, false]                         Build executables as position independentb_sanitize                          none                                  [none, address, thread, undefined,    Code sanitizer to usememory, address,undefined]            b_staticpic                         true                                  [true, false]                         Build static libraries as position independentCompiler options                    Current Value                         Possible Values                       Description----------------                    -------------                         ---------------                       -----------c_args                              []                                                                          Extra arguments passed to the c compilerc_link_args                         []                                                                          Extra arguments passed to the c linkerc_std                               gnu99                                 [none, c89, c99, c11, c17, c18, c2x,  C language standard to usegnu89, gnu99, gnu11,                  gnu17, gnu18, gnu2x]                 cpp_args                            []                                                                          Extra arguments passed to the cpp compilercpp_debugstl                        false                                 [true, false]                         STL debug modecpp_eh                              default                               [none, default, a, s, sc]             C++ exception handling type.cpp_link_args                       []                                                                          Extra arguments passed to the cpp linkercpp_rtti                            true                                  [true, false]                         Enable RTTIcpp_std                             c++17                                 [none, c++98, c++03, c++11, c++14,    C++ language standard to usec++17, c++1z, c++2a, c++20,           gnu++03, gnu++11, gnu++14, gnu++17,  gnu++1z, gnu++2a,                     gnu++20]                             Directories                         Current Value                         Possible Values                       Description-----------                         -------------                         ---------------                       -----------bindir                              bin                                                                         Executable directorydatadir                             share                                                                       Data file directoryincludedir                          include                                                                     Header file directoryinfodir                             share/info                                                                  Info page directorylibdir                              lib/aarch64-linux-gnu                                                       Library directorylibexecdir                          libexec                                                                     Library executable directorylocaledir                           share/locale                                                                Locale data directorylocalstatedir                       /var/local                                                                  Localstate data directorymandir                              share/man                                                                   Manual page directoryprefix                              /usr/local                                                                  Installation prefixsbindir                             sbin                                                                        System executable directorysharedstatedir                      /var/local/lib                                                              Architecture-independent data directorysysconfdir                          etc                                                                         Sysconf data directoryTesting options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------errorlogs                           true                                  [true, false]                         Whether to print the logs from failing testsstdsplit                            true                                  [true, false]                         Split stdout and stderr in test logsProject options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------alsa                                auto                                  [enabled, disabled, auto]             Enable alsa spa plugin integrationaudioconvert                        enabled                               [enabled, disabled, auto]             Enable audioconvert spa plugin integrationaudiomixer                          enabled                               [enabled, disabled, auto]             Enable audiomixer spa plugin integrationaudiotestsrc                        enabled                               [enabled, disabled, auto]             Enable audiotestsrc spa plugin integrationavahi                               auto                                  [enabled, disabled, auto]             Enable code that depends on avahibluez5                              auto                                  [enabled, disabled, auto]             Enable bluez5 spa plugin integrationbluez5-backend-hfp-native           enabled                               [enabled, disabled, auto]             Enable HFP in native backend in bluez5 spa pluginbluez5-backend-hsp-native           enabled                               [enabled, disabled, auto]             Enable HSP in native backend in bluez5 spa pluginbluez5-backend-hsphfpd              enabled                               [enabled, disabled, auto]             Enable hsphfpd backend in bluez5 spa plugin (no dependency on hsphfpd)bluez5-backend-ofono                enabled                               [enabled, disabled, auto]             Enable oFono HFP backend in bluez5 spa plugin (no dependency on oFono)bluez5-codec-aac                    auto                                  [enabled, disabled, auto]             Enable Fraunhofer FDK AAC open source codec implementationbluez5-codec-aptx                   auto                                  [enabled, disabled, auto]             Enable AptX Qualcomm open source codec implementationbluez5-codec-ldac                   auto                                  [enabled, disabled, auto]             Enable LDAC Sony open source codec implementationcontrol                             enabled                               [enabled, disabled, auto]             Enable control spa plugin integrationdbus                                enabled                               [enabled, disabled, auto]             Enable code that depends on dbusdocdir                                                                                                          Directory for installing documentation to (defaults topipewire_datadir/doc/meson.project_name() )docs                                disabled                              [enabled, disabled, auto]             Build documentationecho-cancel-webrtc                  auto                                  [enabled, disabled, auto]             Enable WebRTC-based echo cancellerevl                                 disabled                              [enabled, disabled, auto]             Enable EVL support spa plugin integrationexamples                            enabled                               [enabled, disabled, auto]             Build examplesffmpeg                              disabled                              [enabled, disabled, auto]             Enable ffmpeg spa plugin integrationgstreamer                           auto                                  [enabled, disabled, auto]             Build GStreamer pluginsgstreamer-device-provider           auto                                  [enabled, disabled, auto]             Build GStreamer device provider plugininstalled_tests                     disabled                              [enabled, disabled, auto]             Install manual and automated test executablesjack                                auto                                  [enabled, disabled, auto]             Enable jack spa plugin integrationjack-devel                          false                                 [true, false]                         Install jack development fileslibcamera                           auto                                  [enabled, disabled, auto]             Enable libcamera spa plugin integrationlibcanberra                         auto                                  [enabled, disabled, auto]             Enable code that depends on libcanberralibjack-path                                                                                                    Where to install the libjack.so librarylibpulse                            auto                                  [enabled, disabled, auto]             Enable code that depends on libpulselibusb                              auto                                  [enabled, disabled, auto]             Enable code that depends on libusblibv4l2-path                                                                                                    Where to install the libpw-v4l2.so librarylv2                                 auto                                  [enabled, disabled, auto]             Enable loading of LV2 pluginsman                                 auto                                  [enabled, disabled, auto]             Build manpagespipewire-alsa                       auto                                  [enabled, disabled, auto]             Enable pipewire-alsa integrationpipewire-jack                       enabled                               [enabled, disabled, auto]             Enable pipewire-jack integrationpipewire-v4l2                       enabled                               [enabled, disabled, auto]             Enable pipewire-v4l2 integrationpw-cat                              auto                                  [enabled, disabled, auto]             Build pw-cat/pw-play/pw-recordraop                                auto                                  [enabled, disabled, auto]             Enable module for Remote Audio Output Protocolroc                                 auto                                  [enabled, disabled, auto]             Enable code that depends on roc toolkitsdl2                                auto                                  [enabled, disabled, auto]             Enable code that depends on SDL 2session-managers                    [media-session]                                                             Session managers to build (can be [] for none or an absolute path)sndfile                             auto                                  [enabled, disabled, auto]             Enable code that depends on libsndfilespa-plugins                         enabled                               [enabled, disabled, auto]             Enable spa plugins integrationsupport                             enabled                               [enabled, disabled, auto]             Enable support spa plugin integrationsystemd                             auto                                  [enabled, disabled, auto]             Enable systemd integrationsystemd-system-service              disabled                              [enabled, disabled, auto]             Install systemd system service filesystemd-system-unit-dir                                                                                         Directory for system systemd units (defaults to /usr/lib/systemd/system)systemd-user-service                enabled                               [enabled, disabled, auto]             Install systemd user service file (ignored without systemd)systemd-user-unit-dir                                                                                           Directory for user systemd units (defaults to /usr/lib/systemd/user)test                                disabled                              [enabled, disabled, auto]             Enable test spa plugin integrationtests                               enabled                               [enabled, disabled, auto]             Build testsudev                                auto                                  [enabled, disabled, auto]             Enable Udev integrationudevrulesdir                                                                                                    Directory for udev rules (defaults to /lib/udev/rules.d)v4l2                                auto                                  [enabled, disabled, auto]             Enable v4l2 spa plugin integrationvideoconvert                        enabled                               [enabled, disabled, auto]             Enable videoconvert spa plugin integrationvideotestsrc                        enabled                               [enabled, disabled, auto]             Enable videotestsrc spa plugin integrationvolume                              enabled                               [enabled, disabled, auto]             Enable volume spa plugin integrationvulkan                              disabled                              [enabled, disabled, auto]             Enable vulkan spa plugin integrationx11                                 auto                                  [enabled, disabled, auto]             Enable code that depends on X11x11-xfixes                          auto                                  [enabled, disabled, auto]             Enable code that depends on XFixesSubproject media-session:Core options                        Current Value                         Possible Values                       Description------------                        -------------                         ---------------                       -----------default_library                     shared                                [shared, static, both]                Default library typewarning_level                       3                                     [0, 1, 2, 3]                          Compiler warning level to usewerror                              false                                 [true, false]                         Treat warnings as errorsProject options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------docdir                                                                                                          Directory for installing documentation to (defaults topipewire_datadir/doc/meson.project_name() )docs                                disabled                              [enabled, disabled, auto]             Build documentationinstalled_tests                     disabled                              [enabled, disabled, auto]             Install manual and automated test executablessystemd                             auto                                  [enabled, disabled, auto]             Enable systemd integrationsystemd-system-service              disabled                              [enabled, disabled, auto]             Install systemd system service filesystemd-user-service                enabled                               [enabled, disabled, auto]             Install systemd user service file (ignored without systemd)systemd-user-unit-dir                                                                                           Directory for user systemd units (defaults to /usr/lib/systemd/user)tests                               enabled                               [enabled, disabled, auto]             Build testswith-module-sets                    [jack, pulseaudio]                    [alsa, jack, pulseaudio]              Extra modules sets to enable on install (see media-session.conf)

定义安装目录前缀:

$ meson configure builddir -Dprefix=/usr # Default: /usr/local

PipeWire 特有的构建选项在 Project options 部分展示,它们在 meson_options.txt 文件中定义。

最后,调用如下命令构建 PipeWire:

$ ninja -C builddir

如果想要在不安装 PipeWire 的情况运行它,可以先运行一个脚本,它会创建一个 PipeWire 可以从构建目录运行的环境,其中 ALSA、PulseAudio 和 JACK 应用程序将自动地使用 PipeWire 仿真库。这个脚本具体的执行方法如下:

$ ./pw-uninstalled.sh -b builddir

pw-uninstalled.sh 脚本内容如下:

#!/usr/bin/env bashset -eSCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"while getopts ":b:v:" opt; docase ${opt} inb)BUILDDIR=${OPTARG};;v)VERSION=${OPTARG}echo "Version: ${VERSION}";;\?)echo "Invalid option: -${OPTARG}"exit 1;;:)echo "Option -${OPTARG} requires an argument"exit 1;;esac
doneif [ -z "${BUILDDIR}" ]; thenBUILDDIR=${SCRIPT_DIR}/builddirecho "Using default build directory: ${BUILDDIR}"
fiif [ ! -d "${BUILDDIR}" ]; thenecho "Invalid build directory: ${BUILDDIR}"exit 1
fi# the config file read by the daemon
export PIPEWIRE_CONFIG_DIR="${BUILDDIR}/src/daemon"
# the directory with SPA plugins
export SPA_PLUGIN_DIR="${BUILDDIR}/spa/plugins"
export SPA_DATA_DIR="${SCRIPT_DIR}/spa/plugins"
# the directory with pipewire modules
export PIPEWIRE_MODULE_DIR="${BUILDDIR}/src/modules"
export PATH="${BUILDDIR}/src/daemon:${BUILDDIR}/src/tools:${BUILDDIR}/src/media-session:${BUILDDIR}/src/examples:${PATH}"
export LD_LIBRARY_PATH="${BUILDDIR}/src/pipewire/:${BUILDDIR}/pipewire-jack/src/${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"}"
export GST_PLUGIN_PATH="${BUILDDIR}/src/gst/${GST_PLUGIN_PATH+":${GST_PLUGIN_PATH}"}"
# the directory with card profiles and paths
export ACP_PATHS_DIR="${SCRIPT_DIR}/spa/plugins/alsa/mixer/paths"
export ACP_PROFILES_DIR="${SCRIPT_DIR}/spa/plugins/alsa/mixer/profile-sets"
# ALSA plugin directory
export ALSA_PLUGIN_DIR="${BUILDDIR}/pipewire-alsa/alsa-plugins"export PW_UNINSTALLED=1
export PKG_CONFIG_PATH="${BUILDDIR}/meson-uninstalled/:${PKG_CONFIG_PATH}"if [ -d "${BUILDDIR}/subprojects/wireplumber" ]; then# FIXME: find a nice, shell-neutral way to specify a prompt"${SCRIPT_DIR}"/subprojects/wireplumber/wp-uninstalled.sh -b"${BUILDDIR}"/subprojects/wireplumber "${SHELL}"
elif [ -d "${BUILDDIR}/subprojects/media-session" ]; then# FIXME: find a nice, shell-neutral way to specify a prompt"${SCRIPT_DIR}"/subprojects/media-session/media-session-uninstalled.sh -b"${BUILDDIR}"/subprojects/media-session "${SHELL}"
else# FIXME: find a nice, shell-neutral way to specify a prompt${SHELL}
fi

pw-uninstalled.sh 脚本接受构建目录 builddir 作为参数,根据构建工具生成的二进制文件的目录结构,导出 PipeWire 各守护进程或客户端应用程序需要用到的环境变量,如 PIPEWIRE_CONFIG_DIRPIPEWIRE_MODULE_DIRSPA_PLUGIN_DIRLD_LIBRARY_PATHSPA_DATA_DIR 等。

pw-uninstalled.sh 脚本有个 bug:当传入的构建目录 builddir 是个相对路径时,各环境变量也会以相对路径的形式导出。在 PipeWire 的代码仓库根目录执行pw-uninstalled.sh 脚本并检查构建目录的有效性,随后基于构建目录路径导出环境变量,切换到构建目录运行 PipeWire 系统音频服务器,会发现各环境变量指向的路径为无效路径。

从构建目录运行 pipewire 的方法如下:

$ cd builddir/
$ make run

这将会使用默认配置文件配置和启动 pipewire 守护进程。默认的配置文件也将自动启动 pipewire-media-session,一个默认的示例会话管理器,和 pipewire-pulse,一个 PulseAudio 兼容服务器。

正常安装的 PipeWire,它的 pipewire 守护进程、pipewire-media-session 和 pipewire-pulse 是作为 3 个系统服务,各自由 systemd 独立管理的。从构建目录运行的 PipeWire,pipewire 守护进程的配置文件为 pipewire-0.3.48/builddir/src/daemon/pipewire-uninstalled.conf,其中有如下这样一段配置:

context.exec = [#{ path = <program-name> [ args = "<arguments>" ] }## Execute the given program with arguments.## You can optionally start the session manager here,# but it is better to start it as a systemd service.# Run the session manager with -h for options.#{ path = "/media/data/develop/pipewire_0.3.48/pipewire-0.3.48/builddir/subprojects/media-session/media-session-uninstalled.sh" args = "pipewire-media-session" }## You can optionally start the pulseaudio-server here as well# but it is better to start it as a systemd service.# It can be interesting to start another daemon here that listens# on another address with the -a option (eg. -a tcp:4713).#{ path = "/media/data/develop/pipewire_0.3.48/pipewire-0.3.48/builddir/src/daemon/pipewire" args = "-c pipewire-pulse.conf" }
]

pipewire-media-session 和 pipewire-pulse 由 pipewire 守护进程启动。

也可以通过 PIPEWIRE_DEBUG 环境变量启用更多的调试日志,如:

$ cd builddir/
$ PIPEWIRE_DEBUG="D" make run

还可以启动 gdb 来调试运行 pipewire,如:

$ cd builddir/
$ PIPEWIRE_DEBUG="D" make gdb

如果系统中已经安装了 PipeWire,且以 pipewire-media-session 作为媒体会话管理器,则从构建目录运行之前,可能需要先通过 systemd 停掉 pipewire service/socket,如:

$ systemctl --user stop pipewire.service \pipewire.socket \pipewire-media-session.service \pipewire-pulse.service \pipewire-pulse.socket

如果以 wireplumber 作为媒体会话管理器,需要将上面命令中的 pipewire-media-session.service 替换为 wireplumber.service

PipeWire 包含一些库和工具,在 builddir 目录中运行如下命令安装所有这些东西到系统的指定目录:

$ sudo meson install

完整安装的 PipeWire 应该有一个 pipewire 进程,一个 pipewire-media-session (或 WirePlumber) 和一个 pipewire-pulse 进程。PipeWire 通常作为一个 systemd 系统服务来启动。PipeWire 守护进程的配置文件位于 /usr/share/pipewire/pipewire.conf,可以参考这个配置文件中的注释来了解更多关于配置选项的内容。通过 systemd 启动 pipewire 守护进程的方法如下:

$ systemctl --user start pipewire.service pipewire.socket

如果没有在 pipewire.conf 配置文件中启动 media-session,也需要像下面这样启动它:

$ systemctl --user start pipewire-media-session.service

要使它在系统启动时自动启动可以执行如下命令:

$ systemctl --user enable pipewire-media-session.service

可以使用 enable --now 来立即启动它。

对于 wireplumber,启动它的方法与 media-session 类似,唯一的区别是 systemd 激活文件需要替换为 wireplumber.service

pipewire-pulse 进程是 PulseAudio 音频服务器协议的重新实现,并作为一个系统服务在 PipeWire 之上运行。它的二进制可执行文件通常位于 /usr/bin/pipewire-pulse。pipewire-pulse 进程可以通过提供的 systemd 激活文件或 PipeWire 守护进程来启动,可参考 /usr/share/pipewire/pipewire.conf 文件。

通过 systemd 启动 pipewire-pulse 服务的方法如下:

$ systemctl --user start pipewire-pulse.service pipewire-pulse.socket

pipewire-pulse 的二进制可执行文件实际为 pipewire 守护进程二进制可执行文件的符号链接。

PipeWire 的 ALSA 插件在 Fedora 发行版中通常安装在 /usr/lib64/alsa-lib/libasound_module_pcm_pipewire.so,在 Ubuntu 发行版中通常安装在 /usr/lib/x86_64-linux-gnu/alsa-lib/libasound_module_pcm_pipewire.so,还有一个配置文件安装在 /usr/share/alsa/alsa.conf.d/50-pipewire.conf,当以下文件位于 /etc/alsa/conf.d/ 目录中时,插件将被 alsa 拾取:

/etc/alsa/conf.d/50-pipewire.conf -> /usr/share/alsa/alsa.conf.d/50-pipewire.conf
/etc/alsa/conf.d/99-pipewire-default.conf

通过这样的设置,aplay -L 应该可以列出 pipewire: 设备,它们可以被用作普通的 alsa 设备来播放和录音。

PipeWire 音频服务器主程序

PipeWire 音频服务器守护进程 pipewire 和它的 PulseAudio 兼容层 pipewire-pulse 守护进程共用同一个二进制可执行文件,它们的主程序定义 (位于 pipewire/src/daemon/pipewire.c) 如下:

int main(int argc, char *argv[])
{struct pw_context *context = NULL;struct pw_main_loop *loop = NULL;struct pw_properties *properties = NULL;static const struct option long_options[] = {{ "help",	no_argument,		NULL, 'h' },{ "version",	no_argument,		NULL, 'V' },{ "config",	required_argument,	NULL, 'c' },{ "verbose",	no_argument,		NULL, 'v' },{ NULL, 0, NULL, 0}};int c, res = 0;char path[PATH_MAX];const char *config_name;enum spa_log_level level = pw_log_level;if (setenv("PIPEWIRE_INTERNAL", "1", 1) < 0)fprintf(stderr, "can't set PIPEWIRE_INTERNAL env: %m");snprintf(path, sizeof(path), "%s.conf", argv[0]);config_name = basename(path);pw_init(&argc, &argv);while ((c = getopt_long(argc, argv, "hVc:v", long_options, NULL)) != -1) {switch (c) {case 'v':if (level < SPA_LOG_LEVEL_TRACE)pw_log_set_level(++level);break;case 'h':show_help(argv[0], config_name);return 0;case 'V':fprintf(stdout, "%s\n""Compiled with libpipewire %s\n""Linked with libpipewire %s\n",argv[0],pw_get_headers_version(),pw_get_library_version());return 0;case 'c':config_name = optarg;break;default:res = -EINVAL;goto done;}}properties = pw_properties_new(PW_KEY_CONFIG_NAME, config_name,NULL);loop = pw_main_loop_new(&properties->dict);if (loop == NULL) {pw_log_error("failed to create main-loop: %m");res = -errno;goto done;}pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGINT, do_quit, loop);pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGTERM, do_quit, loop);context = pw_context_new(pw_main_loop_get_loop(loop), properties, 0);properties = NULL;if (context == NULL) {pw_log_error("failed to create context: %m");res = -errno;goto done;}pw_log_info("start main loop");pw_main_loop_run(loop);pw_log_info("leave main loop");done:pw_properties_free(properties);if (context)pw_context_destroy(context);if (loop)pw_main_loop_destroy(loop);pw_deinit();return res;
}

pipewire 和 pipewire-pulse 主程序的执行过程如下:

  1. 传入可执行程序执行时的命令行参数,调用 pw_init() 函数初始化 PipeWire,初始化一些基本配置和功能组件。pw_init() 函数在所有 PipeWire 程序中都会被调用,包括 PipeWire 守护进程及其 PulseAudio 兼容层,PipeWire 客户端程序,PipeWire 媒体会话管理器 pipewire-media-session 和 wireplumber。初始化 PipeWire 的具体含义稍后会更细致地来看。
  2. 解析命令行参数。-v 参数指示 PipeWire 进程在执行时输出更多日志,具体指输出日志等级加 1,而不是输出所有日志。-c 参数用来指定配置文件名,配置文件名默认为可执行文件名加上 .conf 后缀,如 pipewire 的为 pipewire.conf,pipewire-pulse 的为 pipewire-pulse.conf,这个参数指定的配置文件名替换默认配置文件名。
  3. 调用 pw_main_loop_new() 函数创建主循环。以 struct spa_dict 对象的形式传递参数,这里参数主要是配置文件名。为主循环添加 SIGINTSIGTERM 信号的处理程序,收到这两个信号时,PipeWire 进程退出主循环。
  4. 基于主循环和配置信息创建上下文。
  5. 运行主循环。
  6. 主循环结束时清理上下文和主循环等对象。

pw_init() 函数初始化一些基本配置和功能组件,该函数定义 (位于 pipewire/src/pipewire/pipewire.c) 如下:

#define MAX_SUPPORT	32#define SUPPORTLIB	"support/libspa-support"PW_LOG_TOPIC_EXTERN(log_context);
#define PW_LOG_TOPIC_DEFAULT log_contextstatic char *prgname;static struct spa_i18n *_pipewire_i18n = NULL;struct plugin {struct spa_list link;char *filename;void *hnd;spa_handle_factory_enum_func_t enum_func;struct spa_list handles;int ref;
};struct handle {struct spa_list link;struct plugin *plugin;char *factory_name;int ref;struct spa_handle handle SPA_ALIGNED(8);
};struct registry {struct spa_list plugins;
};struct support {char **categories;const char *plugin_dir;const char *support_lib;struct registry registry;char *i18n_domain;struct spa_interface i18n_iface;struct spa_support support[MAX_SUPPORT];uint32_t n_support;unsigned int initialized:1;unsigned int in_valgrind:1;unsigned int no_color:1;unsigned int no_config:1;
};static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t support_lock = PTHREAD_MUTEX_INITIALIZER;
static struct support global_support;. . . . . .static void init_i18n(struct support *support)
{/* Load locale from the environment. */setlocale(LC_ALL, "");/* Set LC_NUMERIC to C so that floating point strings are consistently* formatted and parsed across locales. */setlocale(LC_NUMERIC, "C");bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");pw_set_domain(GETTEXT_PACKAGE);
}. . . . . .
SPA_EXPORT
void pw_init(int *argc, char **argv[])
{const char *str;struct spa_dict_item items[6];uint32_t n_items;struct spa_dict info;struct support *support = &global_support;struct spa_log *log;char level[32];pthread_mutex_lock(&init_lock);if (support->initialized)goto done;pthread_mutex_lock(&support_lock);support->in_valgrind = RUNNING_ON_VALGRIND;if (getenv("NO_COLOR") != NULL)support->no_color = true;if ((str = getenv("PIPEWIRE_NO_CONFIG")) != NULL)support->no_config = pw_properties_parse_bool(str);init_i18n(support);if ((str = getenv("SPA_PLUGIN_DIR")) == NULL)str = PLUGINDIR;support->plugin_dir = str;if ((str = getenv("SPA_SUPPORT_LIB")) == NULL)str = SUPPORTLIB;support->support_lib = str;spa_list_init(&support->registry.plugins);if (pw_log_is_default()) {char *patterns = NULL;n_items = 0;if (!support->no_color)items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_COLORS, "true");items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_TIMESTAMP, "true");if ((str = getenv("PIPEWIRE_LOG_LINE")) == NULL || spa_atob(str))items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_LINE, "true");snprintf(level, sizeof(level), "%d", pw_log_level);items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_LEVEL, level);if ((str = getenv("PIPEWIRE_LOG")) != NULL)items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_FILE, str);if ((patterns = parse_pw_debug_env()) != NULL)items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_PATTERNS, patterns);info = SPA_DICT_INIT(items, n_items);log = add_interface(support, SPA_NAME_SUPPORT_LOG, SPA_TYPE_INTERFACE_Log, &info);if (log)pw_log_set(log);#ifdef HAVE_SYSTEMDif ((str = getenv("PIPEWIRE_LOG_SYSTEMD")) == NULL || spa_atob(str)) {log = load_journal_logger(support, &info);if (log)pw_log_set(log);}
#endiffree(patterns);} else {support->support[support->n_support++] =SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_Log, pw_log_get());}pw_log_init();n_items = 0;if ((str = getenv("PIPEWIRE_CPU")))items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_CPU_FORCE, str);if ((str = getenv("PIPEWIRE_VM")))items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_CPU_VM_TYPE, str);info = SPA_DICT_INIT(items, n_items);add_interface(support, SPA_NAME_SUPPORT_CPU, SPA_TYPE_INTERFACE_CPU, &info);add_i18n(support);pw_log_info("version %s", pw_get_library_version());support->initialized = true;pthread_mutex_unlock(&support_lock);
done:pthread_mutex_unlock(&init_lock);
}

PipeWire 程序用 struct support 类型的全局对象 global_support 维护一些基本配置和功能组件,如插件目录、支持库路径、i18n、日志等,以及所有加载的插件,其中所有加载的插件用 struct registry 对象维护,基本功能组件用 struct spa_support 数组维护。

pw_init() 函数初始化 global_support 对象,具体过程如下:

  1. 从环境变量 NO_COLOR、 **PIPEWIRE_NO_CONFIG ** 中获取对应配置,初始化 i18n。从环境变量 SPA_PLUGIN_DIR 获取插件目录,失败时使用默认目录路径,如 /usr/lib/aarch64-linux-gnu/spa-0.2。从环境变量 SPA_SUPPORT_LIB 获取支持库路径,失败时使用默认路径 support/libspa-support。初始化 struct registry

  2. 初始化并添加日志组件。如果全局日志组件为默认日志组件,构造日志组件初始化时的配置参数,除了前面获取的 no_color,还有如下这些配置参数:

    • 是否打印时间戳配置 log.timestamp,为 true
    • 从环境变量 **PIPEWIRE_LOG_LINE ** 中获取的是否打印行号配置 log.line;
    • 打印的最低日志等级配置 log.level
    • 从环境变量 **PIPEWIRE_LOG ** 中获取的是否打印文件配置 log.file
    • 从环境变量 PIPEWIRE_DEBUG 中获取的日志模式配置log.patterns

    之后调用 add_interface() 函数从支持库插件中加载日志组件,并设置全局日志组件为该日志组件。如果环境变量 PIPEWIRE_LOG_SYSTEMD 指示使用 systemd 日志,则调用 load_journal_logger() 函数加载 journal 日志组件替换 支持库插件中加载的日志组件。
    如果全局日志组件不是默认日志组件,则向 global_support 添加全局日志组件为。
    最后,调用 pw_log_init() 函数基于新的全局日志组件,初始化各个日志 topic。
    日志是 PipeWire 配置的第一个组件。

  3. 初始化并添加 CPU 组件。从环境变量 PIPEWIRE_CPUPIPEWIRE_VM 获取配置参数,调用 add_interface() 函数从支持库插件中加载 CPU 组件。

  4. 添加 i18n 组件。

  5. 结束初始化。

global_supportstruct spa_support 数组中维护的这些组件,提供十分基础的全局功能,可以在其它一般插件的实现中使用。全局支持组件主要包括日志、CPU 和 i18n。

相关文章:

PipeWire 音频设计与实现分析一——介绍

PipeWire 是一个基于图的媒体处理引擎&#xff0c;一个可以运行多媒体节点图的媒体服务器&#xff0c;是 Linux 的音频/视频总线&#xff0c;它管理 Linux 系统中&#xff0c;不同应用程序对音频和视频设备的共享访问。它提供了一个本地客户端音频 API&#xff0c;但也提供兼容…...

MVC 文件夹:架构之美,开发之魂

MVC 文件夹&#xff1a;架构之美&#xff0c;开发之魂 引言 在软件开发领域&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;架构模式已经成为了一种广泛应用的架构设计理念。它将应用程序分为三个核心部分&#xff1a;模型&#xff08;Model&#xff09;、视图…...

IO模型之于并发编程模型、并发模型之于架构模式

一、并发编程模型主要包括以下几种‌&#xff1a; ‌多进程模型‌&#xff1a;利用操作系统的进程模型来实现并发。每个用户请求接入时都会创建一个进程&#xff0c;适用于I/O密集型任务。缺点是创建进程的开销高&#xff0c;且上下文切换的开销也大。典型应用如Apache Web Ser…...

Postman 7.3.5 旧版下载指南(Win64)及注意事项

Postman-win64-7.3.5-Setup 是 Postman 的一个旧版本&#xff08;2019年发布&#xff0c;适用于 Windows 64位系统&#xff09;。以下是相关信息和建议&#xff1a; 1. Postman 7.3.5 版本说明 功能&#xff1a;用于 API 开发、测试和协作。 系统要求&#xff1a;Windows 64位…...

​Flink/Kafka在python中的用处

一、基础概念 1. ​Apache Kafka 是什么&#xff1f; ​核心功能&#xff1a;Kafka 是一个分布式流处理平台&#xff0c;主要用于构建实时数据管道和流式应用程序。​核心概念&#xff1a; ​生产者&#xff08;Producer&#xff09;​&#xff1a;向 Kafka 发送数据的程序。…...

【Spring Boot 与 Spring Cloud 深度 Mape 之十】体系整合、部署运维与进阶展望

【Spring Boot 与 Spring Cloud 深度 Mape 之十】体系整合、部署运维与进阶展望 #微服务实战 #Docker #Kubernetes #SpringSecurity #OAuth2 #分布式事务 #Seata #ServiceMesh #总结 #SpringCloud #SpringBoot 系列终章&#xff1a;经过前九篇 [【深度 Mape 系列】] 的系统学习…...

轻松理解Python装饰器:从基础到应用

一、为什么需要装饰器 想象一下&#xff0c;你写了很多函数来完成不同的任务&#xff0c;突然有个新需求&#xff1a;在每个函数执行前打印一条“函数开始执行”的消息&#xff0c;执行后打印“函数执行结束”。如果没有装饰器&#xff0c;你就得在每个函数里手动添加这两条打…...

RabbitMQ 技术详解:异步消息通信的核心原理与实践

这里写目录标题 RabbitMQ 技术详解&#xff1a;异步消息通信的核心原理与实践一、RabbitMQ 本质剖析核心架构组件 二、核心功能与应用场景主要作用典型应用场景 三、工作流程深度解析消息传递流程关键协议机制 四、Java 实现示例1. 依赖配置&#xff08;Maven&#xff09;2. 消…...

MySQL-- 多表查询的分类,SQL92与SQL99,7种JOIN的实现,SQL99语法的新特性

目录 一&#xff0c;多表查询的分类 角度1&#xff1a;等值连接 vs 非等值连接 角度2&#xff1a;自连接 vs 非自连接 角度3&#xff1a;内连接 vs 外连接 二&#xff0c;SQL92语法实现内连接&#xff1a;见上&#xff0c;略SQL92语法实现外连接&#xff1a;使用 -…...

Selenium文件上传

在 Web 自动化测试中,文件上传是一项常见的任务。不同的网站和前端技术可能导致上传方式有所不同,因此需要采用不同的方法进行处理。 方法 1:使用 send_keys() 直接上传(最常用) 适用场景: 页面中 有标准的 <input type="file"> 标签。 不需要弹出 Wind…...

getID3获取本地或远程视频时长

音频文件也可使用&#xff0c;使用ffmeg安装太复杂了 附ffmpeg方式&#xff1a;centos下安装ffmpeg_yum安装ffmpeg-CSDN博客 使用composer先安装 composer require james-heinrich/getid3 获取本地视频 //获取本地视频$video_path $_SERVER[DOCUMENT_ROOT].$params[video];…...

OpenAI流式解析

OpenAI 流式的代码&#xff1a; 首选一般请使用os.getenv 去读环境变量的内容 注意使用pip install python-dotenv 的安装方法 load_dotenv 是这个库提供的一个函数&#xff0c;用于读取 .env 文件并将其中定义的键值对设置为系统的环境变量。 默认情况下&#xff0c;load_…...

在Trae中设置Python解释器版本

Python 是一种广泛使用的高级编程语言&#xff0c;因其简洁易读的语法和强大的功能而备受欢迎。随着 Python 的不断发展&#xff0c;多个版本相继发布&#xff0c;每个版本都带来了新特性和改进。然而&#xff0c;这也带来了一些问题&#xff0c;比如不同的工程&#xff0c;需要…...

第 6 章:优化动态分配内存的变量_《C++性能优化指南》_notes

优化动态分配内存的变量 第六章核心知识点详解总结第六章 动态内存优化 重点难点梳理 一、多选题&#xff08;每题至少2个正确答案&#xff09;二、设计题答案与详解多选题答案设计题答案示例 第六章核心知识点详解 动态内存分配的开销 知识点&#xff1a;动态内存分配需要调用…...

图像数据增强教程:为目标检测任务准备数据

目录 一、简介 二、代码结构 三、环境要求 四、数据增强类 4.1 调整增强概率和参数 4.2 增强方法参数 五、数据增强主函数 六、主函数 效果展示 完整代码 一、简介 在目标检测任务中&#xff0c;数据增强是一种关键技术&#xff0c;通过对原始图像应用多种变换来增加…...

Unity编辑器功能及拓展(2) —Gizmos编辑器绘制功能

Unity中的Gizmos功能是用于在场景视图中绘制辅助图形或图标的工具&#xff0c;帮助开发者在编辑模式下直观调试和可视化游戏对象的位置、范围、方向等信息。 一.定义概述 Gizomsd 概述 Gizoms是Unity提供的一个API&#xff0c;或者叫做一个工具类&#xff0c;包含一系列静态…...

HarmonyOS WebSocket全场景应用开发深度解析

注&#xff1a;适用版本&#xff08;Harmony OS NEXT / 5.0 / API 12 &#xff09; 一、最终效果预览 二、基础代码结构 Entry Component struct ChatApp {State messages: Message[] [] // 所有聊天记录State inputText: string "" // 输入框内容State isCon…...

JCRQ1河马算法+消融实验!HO-CNN-LSTM-Attention系列四模型多变量时序预测

JCRQ1河马算法消融实验&#xff01;HO-CNN-LSTM-Attention系列四模型多变量时序预测 目录 JCRQ1河马算法消融实验&#xff01;HO-CNN-LSTM-Attention系列四模型多变量时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于HO-CNN-LSTM-Attention、CNN-LSTM-Attent…...

ubuntu 安装 postgresql

在 Ubuntu 系统中安装 PostgreSQL 的步骤如下&#xff1a; 步骤 1&#xff1a;更新软件包列表 sudo apt update步骤 2&#xff1a;安装 PostgreSQL Ubuntu 默认仓库包含 PostgreSQL&#xff0c;直接安装&#xff1a; sudo apt install postgresql postgresql-contrib -ypost…...

深入实践:基于WebSocket的全球化金融数据实时对接方案。 马来西亚、印度、美国金融数据API

深入实践&#xff1a;基于WebSocket的全球化金融数据实时对接方案 在全球金融市场中&#xff0c;实时数据的高效获取与处理是量化交易、行情监控等场景的核心能力。本文将以技术实践为核心&#xff0c;详细解析如何通过WebSocket技术实现美国、印度、马来西亚等多国金融数据&a…...

深度学习处理时间序列(5)

Keras中的循环层 上面的NumPy简单实现对应一个实际的Keras层—SimpleRNN层。不过&#xff0c;二者有一点小区别&#xff1a;SimpleRNN层能够像其他Keras层一样处理序列批量&#xff0c;而不是像NumPy示例中的那样只能处理单个序列。也就是说&#xff0c;它接收形状为(batch_si…...

Linux: 进程间通信

目录 一 前言 二 进程间通信目的 三 进程间通信方法 四 管道通信 1. 进程如何通信 2.管道概念 2.1匿名管道 2.2 匿名管道对多个进程的控制 2.3 命名管道 2.4 命名管道原理 一 前言 在我们学习进程的时候&#xff0c;我们知道正是因为程序地址空间的存在&#xff…...

为什么idea显示数据库连接成功,但操作数据库时,两边数据不同步

今日份小bug又叕又来了&#xff01; 一、原因分析 1. 未提交的事务 - IDEA 中执行了修改操作但未提交事务 - 其他客户端有未提交的修改 2. 连接隔离级别问题 - 不同连接使用了不同的事务隔离级别 - 读未提交(READ UNCOMMITTED)导致看到未提交数据 3. 多客户端同时操作…...

VMware中新建Ubuntu虚拟机系统,并安装Anaconda

详细介绍 Ubuntu18.04版本的安装Anaconda的安装 Ubuntu20.04版本的安装给出其他参考 安装Ubuntu18.04 新建虚拟机 如果不习惯图文形式的&#xff0c;也可参考该up主的环境安装分享&#xff0c;和我如下记录有些不同&#xff0c;但不影响&#xff0c;大部分均一致。 …...

LangChain 基础系列之 Prompt 工程详解:从设计原理到实战模板

LangChain 基础系列之 Prompt 工程详解&#xff1a;从设计原理到实战模板 一、揭开 LangChain 的 “灵魂引擎”&#xff1a;Prompt 的核心作用 在 LangChain 构建的智能应用中&#xff0c;Prompt&#xff08;提示词&#xff09;堪称驱动大模型的 “神经中枢”。这个承载着任务…...

项目如何安装本地tgz包并配置局部registry

一、判断包来源是否正确 1. 检查url curl <registry_url>2. 查看包是否存在 npm view <package_name> --registry<registry_url>二、局部registry配置步骤&#xff1a; 1. 全局配置 如果你希望对所有项目生效&#xff0c;可以将这行配置添加到全局.npmr…...

unity客户端面试高频2(自用)

标题是我 1.构造函数为什么不能为虚函数&#xff1f;析构函数为什么要虚函数&#xff1f;2.C智能指针3.左值和右值完美转发 4.深拷贝与浅拷贝5.malloc VS new 你们知道吗 1.构造函数为什么不能为虚函数&#xff1f;析构函数为什么要虚函数&#xff1f; 构造函数不能定义为虚函…...

【12】Ajax的原理和解析

一、前言 二、什么是Ajax 三、Ajax的基本原理 3.1 发送请求 3.2 解析内容 3.3 渲染网页 3.4 总结 四、Ajax 分析 五、过滤请求-筛选所有Ajax请求 一、前言 当我们在用 requests 抓取页面的时候&#xff0c;得到的结果可能会和在浏览器中看到的不一样&a…...

深度学习在测距模型中的应用

一、单目视觉测距和双目视觉测距简介 1、单目视觉测距 模型&#xff1a;深度估计&#xff08;Depth Estimation&#xff09; 原理&#xff1a;通过深度学习模型&#xff08;如MonoDepth2、MiDaS&#xff09;或传统的计算机视觉方法&#xff08;如单目相机结合物体大小推断&am…...

Python np.vectorize函数介绍

np.vectorize 是 NumPy 提供的一个 用于将标量函数(scalar function)向量化 的工具,使其可以作用于 NumPy 数组,类似于 通用函数(ufunc) 的行为。 1️⃣ np.vectorize 语法 numpy.vectorize(pyfunc, otypes=None, signature=None, excluded=None, cache=False)📌 参数…...

HarmonyOS NEXT状态管理实践

在HarmonyOS NEXT开发中&#xff0c;状态管理是构建高效、响应式应用的核心。本文深入探讨状态管理的最佳实践&#xff0c;结合代码示例与案例分析&#xff0c;帮助开发者掌握这一关键技能。 一、状态管理装饰器的合理使用 HarmonyOS NEXT提供多种状态管理装饰器&#xff0c;…...

广告牌变“高空炸弹“?智能预警终端筑起安全防线!

近年来&#xff0c;随着城市发展步伐加快&#xff0c;广告牌已成为城市形象的重要载体。但与此同时&#xff0c;因设计缺陷、违规搭建、维护缺失等问题导致的广告牌坠落事故频发&#xff0c;给市民生命财产安全带来严重威胁。据不完全统计&#xff0c;我国2000万块户外广告牌中…...

scss预处理器对比css的优点以及基本的使用

本文主要在vue中演示&#xff0c;scss的基本使用。安装命令 npm install sass sass-loader --save-dev 变量 SCSS 支持变量&#xff0c;可将常用的值&#xff08;如颜色、字体大小、间距等&#xff09;定义为变量&#xff0c;方便重复使用和统一修改。 <template><…...

Redis 单线程

Redis 读写是否是单线程&#xff1f; 核心数据操作仍然是单线程 Redis 主要采用 单线程执行命令&#xff0c;这是因为&#xff1a; 避免加锁&#xff1a;如果多个线程并发修改数据&#xff0c;就需要加锁&#xff0c;而 Redis 采用单线程保证操作的原子性&#xff0c;无需加…...

Node.js 下载安装及环境配置教程、卸载删除环境配置超详细步骤(附图文讲解!) 从零基础入门到精通,看完这一篇就够了

Node.js 安装 一、进入官网地址下载安装包 Node.js — Download Node.js 选择对应你系统的Node.js版本&#xff0c;这里我选择的是Windows系统、64位 Tips&#xff1a;如果想下载指定版本&#xff0c;点击【以往的版本】&#xff0c;即可选择自己想要的版本下载 二、安装程序…...

第十五章:Python的Pandas库详解及常见用法

在数据分析领域&#xff0c;Python的Pandas库是一个不可或缺的工具。它提供了高效的数据结构和数据分析工具&#xff0c;使得数据处理变得简单而直观。本文将详细介绍Pandas库的基本功能、常见用法&#xff0c;并通过示例代码演示如何使用Pandas进行数据处理。最后&#xff0c;…...

Windows下VSCode的安装

前言 VSCode的安装看起来平平无奇&#xff0c;但也不是轻轻松松的。笔者将最新的Windows下安装VSCode&#xff0c;以及运行最简单的C程序的过程记录下来&#xff0c;供后续的自己和大家参考。 一、官网下载安装包 Visual Studio Code - Code Editing. Redefined 二、安装 直接…...

PgDog:一个PostgreSQL分布式集群中间件

PgDog 是一个实现了 PostgreSQL 分片、连接池以及负载均衡功能的中间。PgDog 使用 Rust 语言编写&#xff0c;支持跨平台&#xff08;Linux、Mac OS、Windows&#xff09;&#xff0c;具有高性能和高可靠性&#xff0c;可以在不需要修改任何应用程序的前提下实现 PostgreSQL 数…...

基于yolov11的棉花品种分类检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv11的棉花品种分类检测系统是一种高效、准确的农作物品种识别工具。该系统利用YOLOv11深度学习模型&#xff0c;能够实现对棉花主要品种&#xff0c;包括树棉&#xff08;G. arboreum&#xff09;、海岛棉&#xff08;G. barbadense&#xff09;、草棉&a…...

Web网页内嵌福昕OFD版式办公套件实现在线预览编辑PDF、OFD文档

PDF&#xff0c;即Portable Document Format&#xff0c;用于以一种独立于应用程序、硬件、操作系统的方式共享和查看文档&#xff1b;OFD&#xff0c;即Office Open Document Format for Document&#xff0c;是一种在政府公文和法律文件等领域广泛应用的电子文件格式&#xf…...

UE4学习笔记 FPS游戏制作32 主菜单,暂停游戏,显示鼠标指针

文章目录 一主菜单搭建UI显示主菜单时&#xff0c;暂停游戏&#xff0c;显示鼠标绑定按钮 二 打开主菜单 一主菜单 搭建UI 添加一个MainUi的控件 添加一个返回游戏的按钮和一个退出游戏的按钮 修改一下样式&#xff0c;放中间 显示主菜单时&#xff0c;暂停游戏&#xff0…...

多线程 - 线程安全引入

写一个代码&#xff0c;让主线程创建一个新的线程&#xff0c;由新的线程负责完成一系列的运算&#xff08;比如&#xff1a;1 2 3 ... 1000&#xff09;&#xff0c;再由主线程负责获取到最终结果。 但打印结果为 result 0&#xff0c;略微思考&#xff0c;明白了要让 t 线…...

Angular项目改端口号

在 Angular 项目中修改开发服务器的端口号&#xff08;默认是 4200&#xff09;&#xff0c;可以通过以下几种方式实现&#xff1a; 方法 1&#xff1a;通过 ng serve 命令行参数 直接在运行 ng serve 时指定端口号&#xff1a; ng serve --port 4300效果&#xff1a;开发服务…...

论文内可解释性分析

目录 3 TEPM(Text-Enhanced Prototype Module)3.1 为什么要进行文本增强?(动机)3.2 为什么要使用 Concat(Fv, T) 和 Repeat(T) + Fv?3.3 为什么 Q=F_C,K=V=F_R ?(第一层注意力)3.4 为什么要进行两层注意力?3.5 为什么最终结果会更好?**3.6 面试官可能问的挑战性问题*…...

《C++11:通过thread类编写C++多线程程序》

关于多线程的概念与理解&#xff0c;可以先了解Linux下的底层线程。当对底层线程有了一定程度理解以后&#xff0c;再学习语言级别的多线程编程就轻而易举了。 【Linux】多线程 -&#xff1e; 从线程概念到线程控制 【Linux】多线程 -&#xff1e; 线程互斥与死锁 语言级别的…...

@Resource 与 @Autowired:Spring 中的依赖注入注解大比拼

在 Spring 框架中&#xff0c;依赖注入&#xff08;DI&#xff09;是核心功能之一&#xff0c;它允许开发者将组件之间的依赖关系交给 Spring 容器管理&#xff0c;从而实现解耦和更灵活的代码结构。Resource 和 Autowired 是两种常用的依赖注入注解&#xff0c;它们虽然功能相…...

大模型学习:从零到一实现一个BERT微调

目录 一、准备阶段 1.导入模块 2.指定使用的是GPU还是CPU 3.加载数据集 二、对数据添加词元和分词 1.根据BERT的预训练&#xff0c;我们要将一个句子的句头添加[CLS]句尾添加[SEP] 2.激活BERT词元分析器 3.填充句子为固定长度 代码解释&#xff1a; 三、数据处理 1.…...

Git和GitCode使用(从Git安装到上传项目一条龙)

第一步 菜鸟教程-Git教程 点击上方链接&#xff0c;完成Git的安装&#xff0c;并了解Git 工作流程&#xff0c;知道Git 工作区、暂存区和版本库的区别 第二步 GitCode官方帮助文档-SSH 公钥管理 点击上方链接&#xff0c;完成SSH公钥设置 第三步&#xff08;GitCode的官方引…...

NodeJs之http模块

一、概念&#xff1a; 1、协议&#xff1a;双方必须共同遵从的一组约定。 Hypertext Transfer Protocol&#xff1a;HTTP&#xff0c;超文本传输协议 2、请求&#xff1a; ① 请求报文的组成&#xff1a; 请求行请求头空行请求体 ② 请求行&#xff1a; 请求方法URLHTTP版本…...

【深度学习与实战】2.3、线性回归模型与梯度下降法先导案例--最小二乘法(向量形式求解)

为了求解损失函数 对 的导数&#xff0c;并利用最小二乘法向量形式求解 的值‌ 这是‌线性回归‌的平方误差损失函数&#xff0c;目标是最小化预测值 与真实值 之间的差距。 ‌损失函数‌&#xff1a; 考虑多个样本的情况&#xff0c;损失函数为所有样本的平方误差之和&a…...