Come posso passare da un hardware di uscita audio diverso usando la shell?


34

Uso il mio laptop con un monitor esterno dotato di altoparlanti. Quando il monitor è collegato tramite HDMI, posso passare (usando la GUI: Sound Setting -> Hardware) tra la normale uscita audio del laptop e l'uscita del monitor.

Ripeto questa procedura per un sacco di tempo e ho iniziato a chiedermi se posso automatizzarla o, comunque, eseguirla in modo più veloce usando la shell.

La mia distro è Ubuntu 12.04 con gnome 3.

MODIFICARE:

Ho provato ad usare pacmd, ma list-sink mi dà solo il dispositivo che sto attualmente usando:

pacmd list-sinks | grep name:
name: <alsa_output.pci-0000_00_1b.0.hdmi-stereo>

Dopo un passaggio dalla GUI:

pacmd list-sinks | grep name:
name: <alsa_output.pci-0000_00_1b.0.analog-stereo>

E se provo a cambiarlo ottengo:

pacmd set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
Welcome to PulseAudio! Use "help" for usage information.
Sink alsa_output.pci-0000_00_1b.0.hdmi-stereo does not exist.

Risposte:


28

In questo caso la carta è sempre la stessa. Ciò che sta cambiando tra uno switch e l'altro è il "profilo della scheda".

Quindi la soluzione che ha funzionato davvero è:

pacmd set-card-profile <cardindex> <profilename>

Nel mio caso ho trovato tutti i profili delle carte con:

pacmd list-cards

E dopo posso passare dagli altoparlanti monitor a quelli laptop con:

pacmd set-card-profile 0 output:hdmi-stereo

E:

pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo

Dove 0 è l'indice della carta:

pacmd list-cards
Welcome to PulseAudio! Use "help" for usage information.
>>> 1 card(s) available.
    index: 0
    name: <alsa_card.pci-0000_00_1b.0>

E infine, per rendere più veloce lo switch, ho impostato due alias nel mio file .bashrc:

alias audio-hdmi='pacmd set-card-profile 0 output:hdmi-stereo+input:analog-stereo'
alias audio-laptop='pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo'

In questo modo posso alternare l'audio dal monitor o dal laptop (cuffie) digitando nella shell: audio-hdmi o audio-laptop


Hm. Il mio pacmd non ha l'opzione 'list-cards' ...
ka3ak,


3

Ho creato uno script molto piccolo basato sui precedenti, che cambia non solo l'audio ma anche l'uscita video. Usa la disper per passare da uno schermo all'altro.

Ecco il codice:

#!/bin/bash

CURRENT_PROFILE=$(pacmd list-cards | grep "active profile" | cut -d ' ' -f 3-)

if [ "$CURRENT_PROFILE" = "<output:hdmi-stereo>" ]; then
        pacmd set-card-profile 0 "output:analog-stereo+input:analog-stereo"
        disper -s
else 
        pacmd set-card-profile 0 "output:hdmi-stereo"
        disper -S        
fi

Per me è particolarmente utile poiché non mi piace clonare i display. Uso l'uno o l'altro. Potrebbe essere necessario adattare i profili audio al proprio sistema specifico.


2

Puoi usare pactl, leggi la sua pagina man per maggiori informazioni.


2

Lo script Python di Lukas ( https://github.com/lkettenb/sound-output-switcher , pubblicato sopra) per implementare un'applet di notifica funziona bene. Ha bisogno del pacchetto appindicator. Che può essere installato con

sudo apt-get install python-appindicator

3
Includi almeno alcune parole nella tua risposta che spieghi cos'è lo script e perché è utile.
derobert,


0

Come ho detto qui (probabilmente un duplicato), un'alternativa a Sound Switcher Indicator (che richiede l'aggiunta di un PPA):

In una riga

Nel mio caso è stato hdmi-stereo-extra1+inputprofilo, così in una sola riga sarebbe: [[ $(pacmd list-cards | grep "active profile" | cut -d " " -f 3-) = "<output:hdmi-stereo-extra1+input:analog-stereo>" ]] && pacmd set-card-profile 0 "output:analog-stereo+input:analog-stereo" || pacmd set-card-profile 0 "output:hdmi-stereo-extra1+input:analog-stereo".

Puoi usare un collegamento personalizzato per eseguirlo bash -c(ti avviserà se c'è qualche conflitto con un altro collegamento):

inserisci qui la descrizione dell'immagine

Inoltre puoi aggiungerne uno aliasal tuo .bashrc.

In una sceneggiatura

Ho apportato alcune modifiche in base alla risposta @ user829996 (e qui @ user56655):

#!/bin/bash
set -euo pipefail # strict mode

activeProfile() { pacmd list-cards | grep "active profile" | cut -d " " -f 3-; }
CURRENT_PROFILE="$(eval activeProfile)"

# If it doesn't work run  pacmd list-cards  and try the other outputs from profile section
ANALOG_PROFILE="output:analog-stereo+input:analog-stereo"
HDMI_PROFILE="output:hdmi-stereo-extra1+input:analog-stereo"

if [ "$CURRENT_PROFILE" = "<output:hdmi-stereo-extra1+input:analog-stereo>" ] ; then
  pacmd set-card-profile 0 "$ANALOG_PROFILE"
else
    pacmd set-card-profile 0 "$HDMI_PROFILE"
fi

activeProfile

0

Ho creato il seguente script Python che esegue le seguenti operazioni:

  1. Passa dal dispositivo predefinito al dispositivo successivo nell'elenco (con avvolgimento) indipendentemente dall'ID
  2. Sposta tutte le applicazioni in esecuzione su questo dispositivo.
  3. Invia una notifica alla GUI con il nome del dispositivo.
#!/usr/bin/env python3
import subprocess
# Toggle default device to the next device (wrap around the list)
cards_info = subprocess.run(['pacmd','list-sinks'], stdout=subprocess.PIPE)
card_indexes = subprocess.run(['grep', 'index'], stdout=subprocess.PIPE, input=cards_info.stdout)
indexes_list = card_indexes.stdout.decode().splitlines()
card_descriptions = subprocess.run(['grep', 'device.description'], stdout=subprocess.PIPE, input=cards_info.stdout)
indices = [i for i, s in enumerate(indexes_list) if '*' in s]
if (len(indices) != 1):
    print("Error finding default device")
    exit(1)
default_index = indices[0]
next_default = 0
if (default_index != (len(indexes_list) - 1)):
    next_default = default_index + 1
next_default_index =  (indexes_list[next_default].split("index: ",1)[1])
subprocess.run(['pacmd','set-default-sink %s' %(next_default_index)], stdout=subprocess.PIPE)

# Move all existing applications to the new default device
inputs_info = subprocess.run(['pacmd','list-sink-inputs'], stdout=subprocess.PIPE)
inputs_indexes = subprocess.run(['grep', 'index'], stdout=subprocess.PIPE, input=inputs_info.stdout)
inputs_indexes_list = inputs_indexes.stdout.decode().splitlines()
for line in inputs_indexes_list:
    input_index =  (line.split("index: ",1)[1])
    subprocess.run(['pacmd','move-sink-input %s %s' %(input_index, next_default_index)], stdout=subprocess.PIPE)

# Send notification to the GUI
descriptions_list = card_descriptions.stdout.decode().splitlines()
if (len(descriptions_list) == len(indexes_list)):
    description =  (descriptions_list[next_default].split("= ",1)[1])[1:-1]
    args = ["notify-send", "Default audio card changed", 'Default audio card was set to %s' %(description)]
    subprocess.run(args, stdout=subprocess.PIPE)

Ho assegnato una scorciatoia da tastiera alla sceneggiatura e ora la mia vita è felice

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.