如何通过命令行为各应用分配特定音频输出设备及脚本实现
如何通过命令行按应用分配音频输出到特定设备(含虚拟设备创建/销毁)
刚好之前折腾过PulseAudio的命令行音频路由,这就给你拆解清楚怎么用pacmd/pactl(后者更适合脚本自动化)实现你要的需求,完全替代pavucontrol的可视化操作:
1. 定位Firefox的音频输入实例
首先得找到Firefox对应的音频输入ID(或者客户端标识),因为PulseAudio里每个播放音频的应用实例对应一个sink-input:
# 方式1:获取所有Firefox的sink-input ID(适合多标签页/多实例场景) FIREFOX_INPUT_IDS=$(pactl list sink-inputs | grep -B5 -A5 'application.name = "firefox"' | grep 'Sink Input' | awk '{print $3}') # 方式2:如果只需要单个Firefox客户端ID,也可以这么查 FIREFOX_CLIENT_ID=$(pactl list clients | grep -B2 -A10 'Name: firefox' | grep 'Client ID' | awk '{print $3}')
注意:如果Firefox当前没有播放音频,可能查不到
sink-input,可以先让Firefox播放一段音频再执行命令。
2. 创建虚拟音频设备(虚拟Sink/Source)
用pactl load-module加载PulseAudio的虚拟设备模块,我们这里用module-null-sink创建一个无输出的虚拟sink(如果需要捕获这个设备的音频,它会自动生成对应的monitor source):
# 创建虚拟sink,记录模块ID(后面销毁设备要用到) VIRTUAL_SINK_MODULE=$(pactl load-module module-null-sink sink_name=VirtualFirefoxSink sink_properties=device.description="Virtual_Sink_For_Firefox") # 可选:如果需要独立的虚拟输入设备,加载这个模块 # VIRTUAL_SOURCE_MODULE=$(pactl load-module module-virtual-source source_name=VirtualFirefoxSource source_properties=device.description="Virtual_Source_For_Firefox")
这里的sink_name是自定义的设备名称,后面分配音频时会用到。
3. 将Firefox音频分配到虚拟设备
拿到Firefox的sink-input ID和虚拟sink名称后,用pactl move-sink-input完成路由:
# 批量处理所有Firefox的音频实例 for INPUT_ID in $FIREFOX_INPUT_IDS; do pactl move-sink-input "$INPUT_ID" VirtualFirefoxSink done # 如果用客户端ID分配(单个实例) # pactl move-sink-input "$FIREFOX_CLIENT_ID" VirtualFirefoxSink
执行完这条命令后,Firefox的音频就会输出到我们创建的虚拟设备了。
4. 使用完毕后销毁虚拟设备
用之前记录的模块ID卸载对应的虚拟设备模块,彻底清理资源:
# 卸载虚拟sink模块 pactl unload-module "$VIRTUAL_SINK_MODULE" # 如果加载了虚拟source,也一并卸载 # pactl unload-module "$VIRTUAL_SOURCE_MODULE"
额外小贴士
- 如果脚本要自动化执行,可以加一些判断逻辑,比如检查
FIREFOX_INPUT_IDS是否为空,避免无效操作 - 要是需要更复杂的虚拟设备(比如把多个应用的音频混流到一个虚拟设备),可以试试
module-combine-sink模块 - 所有命令都需要在PulseAudio运行的环境下执行,一般桌面系统默认都会启动PulseAudio
内容的提问来源于stack exchange,提问作者Velkan
相关产品推荐
相关产品推荐

