从 Shell 更改 PulseAudio 输入/输出?

从 Shell 更改 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

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

答案1

正如 @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

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

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

$ pacmd set-default-sink 0 #doesn't work on my PC :(

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

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

$ pactl list short sink-inputs
290     1       176     protocol-native.c       float32le 2ch 44100Hz
295     1       195     protocol-native.c       float32le 2ch 44100Hz

好的,我们有两个流(ID 290 和 295),它们都附加到接收器1
让我们把它们移到下沉0

$ pactl move-sink-input 290 0
$ pactl move-sink-input 295 0

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

#!/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

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

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

答案2

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

pacmd - Used to reconfigure a PulseAudio sound server during runtime.
pactl - Used to control a running PulseAudio sound server.

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

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(数字越小音量越小)

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

还有一个已经存在的命令行工具可以用于此目的。它的名字是波尼米克斯。它是 PulseAudio 的命令行混音器。提供的链接指向项目 github。它是由一位朋友兼 Arch Linux 可信用户/开发人员开发的。如果您没有运行 Arch,您可以使用make和从源代码编译它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

答案3

在我运行 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

如果我跑步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

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

我的卡的配置文件列表位于pactl list cards输出中的某个位置。

答案4

我无法发表评论,因为这是一个新帐户,但我在 @mreithub 的答案上添加了一些代码,并使其自动循环通过音频输出。

#!/bin/bash
BACKGROUND_RED="`tput setaf 1` "
$BACKGROUND_WHITE="`tput setaf 6` "
FORGROUND_BLACK="`tput setaf 0` "
DIM="`tput dim` "
INVERT="`tput smso`"
BOLD="`tput bold` "
RESET="`tput sgr0` "
CLEAR="`tput clear` "

echo -e "$CLEAR" 
pactl list short sinks >&2
# ------------------------------------

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

if [ "$1" == '-' ]; then
   echo -en "$INVERT$BACKGROUND_WHITE Current sink : $RESET    " >&2
   currentSink=$(pactl list short sinks | grep RUNNING | awk '{print $1}' | head -1)
   if [ -e $currentSink ];then
       currentSink=$(pactl list short sinks | awk '{print $1}' | head -1)
   fi
   pactl list short sinks | grep "^$currentSink" | awk '{print $1,$2}' >&2
   sinks=( $(pactl list short sinks | awk '{print $1}') )
   for (( index=0; index <= (${#sinks[@]} * 2); index++ )); do
       if [ "${sinks[$((index % ${#sinks[@]}))]}" == "$currentSink" ]; then
           newSink="${sinks[$((++index % ${#sinks[@]}))]}"
           break
       fi
   done
else
   newSink="$1"
fi
   echo "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_"
   echo -en "$INVERT$BACKGROUND_RED New sink : $RESET     "
   pactl list short sinks | grep --color "^$newSink" | awk '{print $1,$2}' >&2

pacmd set-default-sink "$newSink" >&2

pactl list short sink-inputs|while read stream; do
   streamId=$(echo -en $stream|cut '-d ' -f1)
   echo -e "$FORGROUND_BLACK$DIM moving stream $streamId $RESET" >&2
   pactl move-sink-input "$streamId" "$newSink" >&2
done

相关内容