Linux Pulseaudio深度解析之pa_context_get_sink_input_info_list用流程与实战(五十七)
简介: CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列【原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

🍉🍉🍉文章目录🍉🍉🍉
🌻1. 前言
本篇目的:
Linux PulseAudio 深度解析之 pa_context_get_sink_input_info_list 调用流程与实战。
要点概括
- 核心功能:查询当前 PulseAudio Server 中所有播放流(Sink Input)的详细信息。
- 工作机制:客户端通过 Native Protocol 向 PulseAudio Daemon 发送列表查询请求,服务端遍历
core->sink_inputs,并把每一个pa_sink_input的信息逐条回调给客户端。 - 典型用途:播放器识别、音频任务管理、播放流迁移、音频调试。
🌻2. 应用场景与用法
pa_context_get_sink_input_info_list() 是 PulseAudio 播放流管理体系中的列表查询接口。
在 PulseAudio 中,Music Player、Video Player、Browser、QQ Music、Spotify 这类正在播放音频的应用,最终都会对应一个 pa_sink_input 对象。
而该接口用于:
一次性枚举当前系统中所有 Sink Input 播放流。
函数原型
pa_operation* pa_context_get_sink_input_info_list(
pa_context *c,
pa_sink_input_info_cb_t cb,
void *userdata);
参数说明
c:
PulseAudio Context
cb:
信息返回回调
userdata:
用户私有数据
返回值
返回 pa_operation 对象
用于查询操作状态、管理生命周期,以及等待服务端返回完整列表结果。
应用场景
pa_context_get_sink_input_info_list() 常见应用场景主要有三类。
第一类是播放器列表展示。当 VLC、浏览器、QQ Music、Spotify 等多个应用同时播放音频时,PulseAudio Server 端会为每个播放流创建对应的 pa_sink_input。通过该接口可以一次性枚举所有播放流,并获取每个播放流的名称、音量、所属 Sink、静音状态和驱动信息,因此可以实现类似音频任务管理器的播放流列表。
第二类是批量音频管理。在实现“显示所有正在播放应用”“批量静音所有播放流”“查找指定应用对应的 Sink Input”“对某一类播放流做策略处理”这类功能时,需要先通过 pa_context_get_sink_input_info_list() 获取完整播放流列表,再根据应用名称、Client、Sink、Proplist 等信息做筛选和控制。
第三类是音频调试与路由分析。在排查播放异常时,可以通过该接口查看所有播放流的采样率、声道数、声道布局、所属 Sink、Driver 名称等信息,用来判断哪些应用正在接入 PulseAudio、是否路由到正确设备,以及不同播放流的音频参数是否符合预期。
🌻3. 调用流程剖析
🌻3.1 核心步骤
1. 应用层发起请求
pa_context_get_sink_input_info_list(
context,
info_cb,
userdata);
2. 创建 pa_operation
内部创建:
pa_operation
表示:
查询 Sink Input 列表
操作。
3. 封装协议数据
构造:
GET_SINK_INPUT_INFO_LIST
请求。
与 pa_context_get_sink_input_info() 不同,列表查询不需要传入单个 Sink Input Index。
4. 发送到 PulseAudio Server
通过:
Native Protocol
发送到 Daemon。
5. 服务端遍历 Sink Input 列表
内部遍历:
core->sink_inputs
逐个获取当前系统中的:
pa_sink_input
对象。
6. 提取每个播放流的属性信息
对每个 pa_sink_input 读取名称、音量、Mute 状态、所属 Sink、Driver、SampleSpec、ChannelMap 等信息。
7. 逐条返回查询结果
服务端把每一个 Sink Input 信息封装成 Reply,并逐条发送给客户端。
8. 触发回调并发送结束标记
客户端会多次进入:
info_cb(...)
每次回调对应一个播放流;当 eol > 0 时,表示列表查询结束。
🌻3.2 调用流程图

🌻3.3 Sink Input 列表查询生命周期图

🌻4. 实战应用案例
#include <pulse/pulseaudio.h>
#include <stdio.h>
static void sink_input_info_cb(
pa_context *c,
const pa_sink_input_info *info,
int eol,
void *userdata) {
if (eol < 0) {
printf("query sink input list failed\n");
return;
}
if (eol > 0) {
printf("sink input list query finished\n");
return;
}
printf("SinkInput Index : %u\n",
info->index);
printf("Name : %s\n",
info->name ? info->name : "unknown");
printf("Owner Module : %u\n",
info->owner_module);
printf("Client : %u\n",
info->client);
printf("Sink : %u\n",
info->sink);
printf("Mute : %d\n",
info->mute);
printf("Driver : %s\n\n",
info->driver ? info->driver : "unknown");
}
void get_sink_input_info_list(
pa_context *context) {
pa_operation *op;
op =
pa_context_get_sink_input_info_list(
context,
sink_input_info_cb,
NULL);
if (!op) {
printf("query sink input list failed\n");
return;
}
pa_operation_unref(op);
}
int main() {
pa_context *context;
/*
* 假设 Context 已连接成功
*/
get_sink_input_info_list(context);
return 0;
}
🌻5. 一句话总结
pa_context_get_sink_input_info_list() 本质上是:
“枚举当前 PulseAudio Server 中所有播放流的详细信息”。
它负责批量获取播放流名称、Stream Volume、Mute 状态、所属 Sink、Driver 信息、SampleSpec 参数和 ChannelMap 信息,是 PulseAudio 播放流列表管理、音频任务管理和音频调试中非常常用的查询接口之一。
更多推荐



所有评论(0)