Escribiendo un script para cambiar el dispositivo de audio de MPD

Os pondré en contexto: Mi ordenador personal tienes unos altavoces muy buenos que uso más bien poco, más por pereza que por otra cosa. Estar cambiando el dispositivo de audio para que la música suene o no por los altavoces en lugar de por los cascos lleva más pulsaciones del ratón de las que estoy dispuesto a dar para una tarea tan repetitiva.

Hoy me he propuesto cambiar eso, ¡y os comparto el método para que vosotros también lo hagáis! Si sois al menos la mitad de vagos que yo supongo que os interesará...

Nota: Aunque los comandos a continuación son válidos para sistemas con PulseAudio, se ha probado con un sistema con Pipewire usando pipewire-pulse.

1. Obtener la lista de dispositivos

pacmd list short sinks

Esto devolverá una pequeña lista de todos los dispositivos de reproducción de audio de nuestro sistema. El primer numerito es el que nos interesa; en mi caso los altavoces son el número 55 y los cascos son el número 57. Los apuntamos.

2. Obtener la lista de clientes

pactl list sink-inputs

Esto devolverá una larga lista con las aplicaciones que están haciendo uso del audio actualmente. Desgraciadamente la versión corta ( pactl list short sink-inputs ) no nos muestra suficiente información, así que tenemos que sudar un poco para manipularla.

3. Obtener el dispositivo asociado a MPD

Así las cosas usamos sed para y grep para hacer manipulaciones. Primero obtenemos todos los clientes de la lista hasta mpd:

pactl list sink-inputs | sed -n '/Sink:/,/mpd/p'

Ahora nos quedamos con las líneas donde se muestran sus números de identificación:

pactl list sink-inputs | sed -n '/Sink:/,/mpd/p' | grep 'Sink:'

Sólo nos interesa el último de ellos (el de MPD):

pactl list sink-inputs | sed -n '/Sink:/,/mpd/p' | grep 'Sink:' | tail -1

Por último nos quedamos únicamente con el número, desechando el resto de la línea:

pactl list sink-inputs | sed -n '/Sink:/,/mpd/p' | grep 'Sink:' | tail -1 | sed "s/[^0-9]//g"

En términos prácticos esto significa que obtendré un 55 si MPD está asociado a los altavoces y un 57 si está asociado a los cascos.

4. Obtener el ID del proceso MPD

De forma similar a la manipulación anterior, obtenemos el ID de MPD:

pactl list sink-inputs | sed -n '/mpd/,/object.id/p' | grep object.id | sed "s/[^0-9]//g"

Este numerito varía de un reinicio a otro, así que no vale con apuntarlo, hay que obtenerlo siempre.

5. Juntándolo todo

Por último usamos pactl move-sink-input [ID] [SINK] para cambiar al dispositivo de audio que queramos. Si añadimos una simple condición IF, podemos hacer que el dispositivo de audio cambie de uno a otro según cuál esté asignado actualmente. Aquí el script final “mpd_switch.sh”:

#!/bin/bash
# 
# Comandos útiles:
#
# pactl list short clients
# pactl list short sinks
# pactl list sink-inputs
# pactl move-sink-input [ID] [SINK]
#
# Dispositivos:
#
# 55: alsa_output.pci-0000_00_1b.0.iec958-stereo
# 57: alsa_output.usb-Conexant_Sennheiser_Main_Audio_00000000-00.pro-output-0

CURRENT_SINK=$(pactl list sink-inputs | sed -n '/Sink:/,/mpd/p' | grep 'Sink:' | tail -1 | sed "s/[^0-9]//g")
MPD_ID=$(pactl list sink-inputs | sed -n '/mpd/,/object.id/p' | grep object.id | sed "s/[^0-9]//g")

if [ $CURRENT_SINK == 57 ]; then
	# Cambiamos a los altavoces
	pactl move-sink-input $MPD_ID 55
else
	# Cambiamos a los cascos
	pactl move-sink-input $MPD_ID 57
fi

Ahora puedo asigna este script a un atajo de teclado (META+ALT+M) y superar mi pereza. ¡Victoria!