如何从 CLI 切换音频设备的音频输出?

pa4*_*080 7 command-line pulseaudio desktop-environments 16.04

我正在尝试从命令行在视频卡的音频输出之间切换。我可以通过 GUI 设置来做到这一点,如图所示。如何以编程方式执行此操作?

在此处输入图片说明

在图片上显示了两个音频设备,每个都有两个输出:

  • (绿色)设备 1 -带有两个输出的内置音频

    • 数字输出
    • 耳机
  • (红色)设备 2 - NVidia GTX 660 的HDMI 音频控制器。视频卡连接了两台显示器:

    • 第一台显示器是LG 电视,它连接到HDMI-0

    • 第二台显示器是LG ULTRAWIDE,它连接到DVI-I-1

所以我想通过命令行在红色输出(两个显示器)之间切换。在我的研究中,我发现的一切都是如何在音频设备(声卡)之间切换。我已经阅读了几个主题作为这些问题:


当第一台显示器LG电视| HDMI-0用作音频输出:

在此处输入图片说明

$ pactl list sinks short
8   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   SUSPENDED
16  alsa_output.pci-0000_03_00.1.hdmi-stereo    module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

$ pacmd list-sinks | grep name:
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>
    name: <alsa_output.pci-0000_03_00.1.hdmi-stereo>
Run Code Online (Sandbox Code Playgroud)

当第二台显示器LG ULTRAWIDE | DVI-I-1用作音频输出:

在此处输入图片说明

$ pactl list sinks short
8   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   SUSPENDED
17  alsa_output.pci-0000_03_00.1.hdmi-stereo-extra1 module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

$ pacmd list-sinks | grep name:
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>
    name: <alsa_output.pci-0000_03_00.1.hdmi-stereo-extra1>
Run Code Online (Sandbox Code Playgroud)

的输出pacmd list-cards,并pactl list cards提供了这里


您可以看到(在这种特殊情况下)我正在寻找一种在sink 16和之间切换的方法sink 17。但是当sink 16出现在 中时pactl list sinkssink 17则不出现,反之亦然。我只能从 GUI 设置中切换它们。有没有办法通过命令行来做到这一点?

pa4*_*080 8

感谢与@Thomas的讨论,我意识到正确的 therms(关键词)是profilecard。就问题概要而言,是输入输出。该音频设备。接收编号并不那么重要,但我们需要它们。

我们可以通过命令pacmd list-cardspactl list cards输出相同信息的命令找到每个卡名的所有可用配置文件:

$ pactl list cards

Card #0
    Name: alsa_card.pci-0000_00_1b.0
    ...
    Profiles:
        input:analog-stereo: Analog Stereo Input (sinks: 0, sources: 1, priority: 60, available: yes)
        output:analog-stereo: Analog Stereo Output (sinks: 1, sources: 0, priority: 6000, available: yes)
        output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (sinks: 1, sources: 1, priority: 6060, available: yes)
        output:analog-surround-21: Analog Surround 2.1 Output (sinks: 1, sources: 0, priority: 800, available: yes)
        ...
    Active Profile: output:iec958-stereo+input:analog-stereo
    ...

Card #1
    Name: alsa_card.pci-0000_03_00.1
    ...
    Profiles:
        output:hdmi-stereo: Digital Stereo (HDMI) Output (sinks: 1, sources: 0, priority: 5400, available: yes)
        output:hdmi-stereo-extra1: Digital Stereo (HDMI 2) Output (sinks: 1, sources: 0, priority: 5200, available: yes)
        output:hdmi-surround-extra1: Digital Surround 5.1 (HDMI 2) Output (sinks: 1, sources: 0, priority: 100, available: yes)
        output:hdmi-surround71-extra1: Digital Surround 7.1 (HDMI 2) Output (sinks: 1, sources: 0, priority: 100, available: yes)
        ...
    Active Profile: output:hdmi-stereo
    ...
Run Code Online (Sandbox Code Playgroud)

可以通过以下格式的命令设置某个配置文件:

pactl set-card-profile output:hdmi-stereo <card name|number> <profile name>
Run Code Online (Sandbox Code Playgroud)

根据提到的四个输出的问题,命令是:

pactl set-card-profile alsa_card.pci-0000_03_00.1 output:hdmi-stereo # LG ULTRAWIDE
pactl set-card-profile alsa_card.pci-0000_03_00.1 output:hdmi-stereo-extra1 # LG TV
pactl set-card-profile alsa_card.pci-0000_00_1b.0 output:iec958-stereo # Digital Output
pactl set-card-profile alsa_card.pci-0000_00_1b.0 output:analog-stereo # Headphones
Run Code Online (Sandbox Code Playgroud)

如此答案中所示,设置新配置文件后,接下来要做的事情是:

 pacmd set-default-sink <sink number of the target profile>
 pacmd move-sink-input "$i" <sink number of the target profile> 
 # where $i is the index number of any active input: pacmd list-sink-inputs   
Run Code Online (Sandbox Code Playgroud)

根据我的需求,在问题中描述,我创建了以下脚本:

#!/bin/bash

# Name: /usr/local/bin/audioswitch
# Usage: audioswitch; audioswitch 1; audioswitch 2;  audioswitch 3; audioswitch 4

CARD_1="pci-0000_03_00.1"             ### HDMI Audio Controller of NVidia GTX 660
CARD_1_PROFILE_1="hdmi-stereo"          # LG ULTRAWIDE
CARD_1_PROFILE_2="hdmi-stereo-extra1"   # LG TV
CARD_0="pci-0000_00_1b.0"             ### Built-in Audio
CARD_0_PROFILE_1="iec958-stereo"        # Digital Output
CARD_0_PROFILE_2="analog-stereo"        # Headphones

# Read the user's input
CHOICE="${@}"
choice() {
    if   [ "$CHOICE" == 1 ]; then CARD="$CARD_1"; PROF="$CARD_1_PROFILE_1" # LG ULTRAWIDE
    elif [ "$CHOICE" == 2 ]; then CARD="$CARD_1"; PROF="$CARD_1_PROFILE_2" # LG TV
    elif [ "$CHOICE" == 3 ]; then CARD="$CARD_0"; PROF="$CARD_0_PROFILE_1" # Digital Output
    elif [ "$CHOICE" == 4 ]; then CARD="$CARD_0"; PROF="$CARD_0_PROFILE_2" # Headphones
    else
        echo -e "\nYou should choice between:"
        echo -e "\n\t[1] LG ULTRAWIDE\n\t[2] LG TV\n\t[3] Digital Output\n\t[4] Headphones\n"
        echo -n "Your choice: "; read CHOICE; echo; choice; # call the function again
    fi
}; choice # call the function

# Set the choosen card profile as sink
pactl set-card-profile "alsa_card.${CARD}" "output:${PROF}";

# Set the default sink to the new one
pacmd set-default-sink "alsa_output.${CARD}.${PROF}" &> /dev/null

# Redirect the existing inputs to the new sink
for i in $(pacmd list-sink-inputs | grep index | awk '{print $2}'); do
    pacmd move-sink-input "$i" "alsa_output.${CARD}.${PROF}" &> /dev/null
done
Run Code Online (Sandbox Code Playgroud)

该脚本已准备好与自定义键盘快捷键一起使用,因为它可以处理第一个位置参数的值 ( 1- 4)。当它在没有额外参数的情况下被调用时,它会询问你的选择:

$ audioswitch 

You should choice between:

    [1] LG ULTRAWIDE
    [2] LG TV
    [3] Digital Output
    [4] Headphones

Your choice: 1
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

4668 次

最近记录:

6 年,7 月 前