¿Cómo puedo cambiar entre diferentes hardware de salida de audio usando el shell?

34

Yo uso mi computadora portátil con un monitor externo que tiene altavoces. Cuando el monitor está conectado a través de HDMI, puedo cambiar (usando la GUI: Configuración de sonido -> Hardware) entre la salida de audio normal de la computadora portátil y la salida del monitor.

Repito este procedimiento muchas veces y comencé a preguntarme si puedo automatizarlo o, de todos modos, ejecutarlo de una manera más rápida usando el shell.

Mi distribución es Ubuntu 12.04 con gnome 3.

EDITAR:

Intenté usar pacmd, pero list-sinks solo me da el dispositivo que estoy usando actualmente:

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

Después de un cambio de GUI:

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

Y si trato de cambiarlo obtengo:

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.
Luigi Massa Gallerano
fuente

Respuestas:

28

En este caso, la tarjeta es siempre la misma. Lo que está cambiando entre un interruptor y otro es el "perfil de tarjeta".

Entonces, la solución que realmente funcionó es:

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

En mi caso encontré todos los perfiles de tarjeta con:

pacmd list-cards

Y después puedo cambiar entre el monitor y los altavoces del portátil con:

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

Y:

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

Donde 0 es el índice de la tarjeta:

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>

Y finalmente, para acelerar el cambio, configuré dos alias en mi archivo .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'

De esta manera, puedo cambiar entre el audio del monitor o de la computadora portátil (auriculares) escribiendo en la carcasa: audio-hdmi o audio-laptop

Luigi Massa Gallerano
fuente
Hm. Mi pacmd no tiene la opción 'list-cards' ...
ka3ak
3

Creé un script muy pequeño basado en los anteriores, que no solo cambia el audio sino también la salida de video. Utiliza el dispersor para cambiar entre pantallas.

Aquí está el código:

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

Para mí es especialmente útil ya que no me gusta clonar las pantallas. Yo uso uno u otro. Es posible que deba adaptar los perfiles de audio a su sistema específico.

usuario56655
fuente
2

Puede usar pactl, lea su página de manual para obtener más información.

favadi
fuente
2

El script de Python de Lukas ( https://github.com/lkettenb/sound-output-switcher , publicado anteriormente) para implementar un applet notificador funciona bien. Necesita el paquete appindicator. Eso se puede instalar con

sudo apt-get install python-appindicator
P.Windridge
fuente
3
Incluya al menos algunas palabras en su respuesta que expliquen qué es el guión y por qué es útil.
derobert
0

Como dije aquí (probablemente un duplicado), una alternativa al Indicador de conmutador de sonido (que requiere agregar un PPA):

En una linea

En mi caso era hdmi-stereo-extra1+inputel perfil, por lo que en una línea sería: [[ $(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".

Puede usar un acceso directo personalizado para ejecutarlo bash -c(le advertirá si hay algún conflicto con otro acceso directo):

ingrese la descripción de la imagen aquí

También puede agregar un aliasa su .bashrc.

En un guión

Hice algunos cambios basados ​​en @ user829996 (y aquí @ user56655) respuesta:

#!/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
Pablo A
fuente
0

Creé el siguiente script de Python que hace lo siguiente:

  1. Cambia el dispositivo predeterminado al siguiente dispositivo en la lista (con ajuste) independientemente de la identificación
  2. Mueve todas las aplicaciones en ejecución a este dispositivo.
  3. Envía notificaciones a la GUI con el nombre 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)

Asigne un atajo de teclado al script, y mi vida es feliz ahora

Nimrod.s
fuente