Como faço para alternar as saídas de áudio de um dispositivo de áudio da CLI?

4

Estou tentando alternar entre as saídas de áudio da minha placa de vídeo na linha de comando. Eu sou capaz de fazer isso através das configurações da GUI, como é mostrado na imagem. Como posso fazer isso de forma programática?

Nafotosãoapresentadosdoisdispositivosdeáudiocomduassaídascada:

  • (verde)Dispositivo1-Áudioincorporadocomduassaídas:

    • Saídadigital
    • Fonesdeouvido
  • (vermelho)Dispositivo2-ControladordeáudioHDMIdaNVidiaGTX660.Paraaplacadevídeosãoconectadosdoismonitores:

    • OprimeiromonitoréoLGTVeestáligadoaHDMI-0.

    • OsegundomonitoréLGULTRAWIDEeestáconectadoaDVI-I-1.

Entãoeuqueromudar,vialinhadecomando,entreessassaídas(monitores,nestecaso).Tudooqueeuencontrei,naminhapesquisa,écomoalternarentreosdispositivosdeáudio(placasdesom).Eujálialgunstópicoscomoestasperguntas:

Quando o primeiro monitor LG TV | HDMI-0 é ativado como saída de áudio:

$ 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>

Quando o segundo monitor LG ULTRAWIDE | DVI-I-1 é ativado como saída de áudio:

< p > >

$ 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>

A saída de pacmd list-cards e pactl list cards é fornecida aqui .

Você pode ver (neste caso específico) que estou procurando uma maneira de alternar entre sink 16 e sink 17 . Mas quando sink 16 é apresentado em pactl list sinks , sink 17 não é apresentado e vice-versa. Eu posso trocá-los apenas das configurações da GUI. Existe uma maneira de fazer isso através da linha de comando?

    
por pa4080 04.03.2018 / 16:00

1 resposta

4

Graças à discussão com @Thomas , percebi que os termos apropriados (palavras-chave) são profile e cartão . Nos termos da pergunta profiles estão as entradas e as saídas . As placas são os dispositivos de áudio . E os números sink não são tão importantes, mas precisamos deles.

Podemos encontrar todos os perfis disponíveis para cada nome de cartão pelo comando pacmd list-cards ou pactl list cards que produz a mesma informação:

$ 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
    ...

Um determinado perfil pode ser definido pelo comando com formato como este:

pactl set-card-profile output:hdmi-stereo <card name|number> <profile name>

De acordo com a pergunta das quatro saídas mencionadas, os comandos são:

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

Como é mostrado em esta resposta , quando o novo perfil é definido, as próximas coisas a fazer são:

 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   

De acordo com minhas necessidades, descritas na pergunta, criei o seguinte script:

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

O script está pronto para ser usado com atalhos de teclado personalizados , porque ele pode manipular o valor ( 1 - 4 ) do primeiro parâmetro posicional. Quando é chamado sem paranetro adicional, ele pedirá a sua escolha:

$ audioswitch 

You should choice between:

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

Your choice: 1
    
por pa4080 06.03.2018 / 22:00