从 Shell 更改 PulseAudio 输入/输出?

Naf*_*Kay 51 alsa audio pulseaudio

除了扬声器和普通麦克风之外,我还有一套不错的无线耳机,我不时使用。

我想编写一个脚本来在一个输入和输出源和另一个之间切换,本质上是在我的耳机和我的扬声器+麦克风之间切换。

我想在这之间改变:

...和这个:

有没有办法让我编写两个输入和输出之间的传输脚本?基本上我正在寻找这样的东西:

CURRENT_INPUT="$(get-current-input-name)"
CURRENT_OUTPUT="$(get-current-output-name)"

if [ "$CURRENT_INPUT" == "Vengeance 2000" ]; then
    set-current-input "HD Pro Webcam C920"
else 
    set-current-input "Vengeance 2000"
fi

if ["$CURRENT_OUTPUT" == "Vengeance 2000" ]; then
    set-current-output "Built-in Audio"
else
    set-current-output "Vengeance 2000"
fi
Run Code Online (Sandbox Code Playgroud)

有没有办法编写这个脚本?

mre*_*hub 77

正如@Teresa-e-Junior 指出的那样pactl,使用的工具是:

首先,我们可能想要获取 PA 接收器的 ID。在我的系统上,这是我得到的:

$ pactl list short sinks
0       alsa_output.pci-0000_01_00.1.hdmi-surround      module-alsa-card.c      s16le 6ch 44100Hz  SUSPENDED
1       alsa_output.pci-0000_00_1b.0.analog-stereo      module-alsa-card.c      s16le 2ch 44100Hz  RUNNING
Run Code Online (Sandbox Code Playgroud)

接收器 1 目前是我的默认接收器。
但现在我希望通过 HDMI(即接收器 0)播放我当前和未来的所有流。

有一个命令可以为 PulseAudio 设置默认接收器,但它似乎对我的 PC 没有任何影响:

$ pacmd set-default-sink 0 #doesn't work on my PC :(
Run Code Online (Sandbox Code Playgroud)

相反,新的流似乎连接到最近有流移动到它的接收器。

因此,让我们告诉 pactl 将所有当前正在播放的流移动到 sink 0。我们首先需要列出它们:

$ pactl list short sink-inputs
290     1       176     protocol-native.c       float32le 2ch 44100Hz
295     1       195     protocol-native.c       float32le 2ch 44100Hz
Run Code Online (Sandbox Code Playgroud)

好的,我们有两个流(ID 290 和 295)都附加到 sink 1
让我们将它们移动到 sink 0

$ pactl move-sink-input 290 0
$ pactl move-sink-input 295 0
Run Code Online (Sandbox Code Playgroud)

所以,应该是这样。现在我们只需要制作一个脚本来为我们工作:

#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 <sinkId/sinkName>" >&2
    echo "Valid sinks:" >&2
    pactl list short sinks >&2
    exit 1
fi

newSink="$1"

pactl list short sink-inputs|while read stream; do
    streamId=$(echo $stream|cut '-d ' -f1)
    echo "moving stream $streamId"
    pactl move-sink-input "$streamId" "$newSink"
done
Run Code Online (Sandbox Code Playgroud)

您可以使用接收器 ID 或接收器名称作为参数来调用它(即要么0或类似的东西alsa_output.pci-0000_01_00.1.hdmi-surround)。

现在您可以将此脚本附加到 udev 事件或快捷键。

  • 我的脚本仍然需要`$ pacmd set-default-sink INDEX`,否则更改音量的键盘命令将继续使用旧的接收器源。 (3认同)

cin*_*lli 16

以下命令可用于操作 PulseAudio 声音服务器:

pacmd - Used to reconfigure a PulseAudio sound server during runtime.
pactl - Used to control a running PulseAudio sound server.
Run Code Online (Sandbox Code Playgroud)

以下是它们如何运作的一些示例:

pacmd list-sinks::列出可能汇的名称索引号

pacmd set-default-sink [sinkname]:: 设置默认输出接收

pacmd set-default-source [sourcename]:: 设置默认输入

pacmd set-sink-volume [index] [volume]:: 设置接收器体积

pacmd set-source-volume index volume::音量控制范围 0 - 65536(数字越小音量越低)

这些只是我从维基和手册页中提取的一些内容。参考了解更多详细信息。或者您可以查看命令--helpman页面。

还有一个命令行工具已经可以用于此目的。它的名字是ponymix。它是 PulseAudio 的命令行混合器。提供的链接是项目 github。它是由朋友和 Arch Linux 可信用户/开发人员开发的。如果你没有运行 Arch,你可以使用makeand从源代码编译它sudo make install

$ ponymix --help
    usage: ponymix [options] <command>... 
Options:
 -h, --help              display this help and exit    
 -c, --card CARD         target card (index or name)
 -d, --device DEVICE     target device (index or name)
 -t, --devtype TYPE      device type
 -N, --notify            use libnotify to announce volume changes
     --source            alias to -t source
     --input             alais to -t source
     --sink              alias to -t sink
     --output            alias to -t sink
     --sink-input        alias to -t sink-input
     --source-output     alias to -t source-output
Device Commands:
  help                   display this message
  defaults               list default devices (default command)
  set-default            set default device by ID
  list                   list available devices
  list-short             list available devices (short form)
  list-cards             list available cards
  list-cards-short       list available cards (short form)
  get-volume             get volume for device
  set-volume VALUE       set volume for device
  get-balance            get balance for device
  set-balance VALUE      set balance for device
  adj-balance VALUE      increase or decrease balance for device
  increase VALUE         increase volume
  decrease VALUE         decrease volume
  mute                   mute device
  unmute                 unmute device
  toggle                 toggle mute
  is-muted               check if muted
Application Commands:
  move DEVICE            move target device to DEVICE
  kill DEVICE            kill target DEVICE
Card Commands:
  list-profiles          list available profiles for a card
  list-profiles-short    list available profiles for a card(short form)
  get-profile            get active profile for card
  set-profile PROFILE    set profile for a card
Run Code Online (Sandbox Code Playgroud)


Rub*_*aro 9

在我运行 Fedora 20 的笔记本电脑上,HDMI 输出在默认配置文件中没有列为接收,而是作为不同的配置文件本身。

我只有 1 个这样的水槽,我的笔记本电脑扬声器上播放着美妙的音乐:

$ pactl list short sinks
8   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   RUNNING
Run Code Online (Sandbox Code Playgroud)

如果我跑步,pactl set-card-profile 0 output:hdmi-stereo那么美妙的音乐正在通过 HDMI 播放。我得到:

$ pactl list short sinks
14  alsa_output.pci-0000_00_1b.0.hdmi-stereo    module-alsa-card.c  s16le 2ch 44100Hz   RUNNING
Run Code Online (Sandbox Code Playgroud)

要恢复默认设置,我只需运行pactl set-card-profile 0 output:analog-stereo+input:analog-stereo. 无论哪种方式,如果我重新启动,默认值都会再次出现。

我的卡的配置文件列表在pactl list cards输出的某个地方。

  • `set-card-profile` 之前没有提到,这是这个答案中最重要的信息。 (7认同)

小智 5

扩展@cinelli 接受的答案,我想出了一个脚本

  • 在必须在脚本中定义的两个接收器/输出设备之间切换,
  • 切换流和默认接收器,因此键盘上的媒体键可以工作
  • 使我的回声消除模块保持不变。

根据需要改变!

#!/bin/bash

# Small script to switch between two hardcoded sound output devices

# Set patterns for devices to be toggled. Have to match to second column
# in output of "pactl list short sinks".
# (Could also hardcode the full names, but this might be a little more robust)
TOGGLE1="Jabra_EVOLVE"
TOGGLE2="Generic_ThinkPad_Dock_USB"

# Discover which sink (output device) is active, and set up toggles
while read -r stream; do
  echo "$stream"
  if echo "$stream" | grep -q "RUNNING"; then
    currentSink=$(echo "$stream" | cut -f2)
  fi
  if echo "$stream" | grep -q "$TOGGLE1"; then
    toggle1Sink=$(echo "$stream" | cut -f2)
  fi
  if echo "$stream" | grep -q "$TOGGLE2"; then
    toggle2Sink=$(echo "$stream" | cut -f2)
  fi
done < <(pactl list short sinks)

# Set up where to switch to
if [ "$currentSink" = "$toggle1Sink" ]; then
  newSink=$toggle2Sink
else
  newSink=$toggle1Sink
fi

# Switch streams AND default sink
pactl list short sink-inputs|while read -r stream; do
    streamId=$(echo "$stream"|cut '-d ' -f1)
    # exclude echo cancellation module, but switch all other streams
    # You can, but don't have to remove if condition if no such module present
    if [ "$streamId" != "0" ]; then
      echo "moving stream $streamId"
      pactl move-sink-input "$streamId" "$newSink"
    fi;
    # Also switch default sink, so media control keys work correctly
    pactl set-default-sink "$newSink"
done
Run Code Online (Sandbox Code Playgroud)