web-dev-qa-db-fra.com

Changer l'entrée / sortie PulseAudio du Shell?

J'ai un casque Nice sans fil que j'utilise de temps en temps, en plus de mes haut-parleurs et de mon microphone normal.

Je voudrais écrire un script pour basculer entre une source d'entrée et de sortie et une autre, essentiellement un commutateur entre mes écouteurs et mes haut-parleurs + microphone.

Je voudrais changer entre ceci:

...et ça:

Existe-t-il un moyen pour moi de scripter un transfert entre les deux entrées et sorties? Essentiellement, je cherche quelque chose comme ça:

CURRENT_INPUT="$(get-current-input-name)"
CURRENT_OUTPUT="$(get-current-output-name)"

if [ "$CURRENT_INPUT" == "Vengeance 2000" ]; then
    set-current-input "HD Pro Webcam C920"
else 
    set-current-input "Vengeance 2000"
fi

if ["$CURRENT_OUTPUT" == "Vengeance 2000" ]; then
    set-current-output "Built-in Audio"
else
    set-current-output "Vengeance 2000"
fi

Existe-t-il un moyen de scénariser cela?

40
Naftuli Kay

Comme l'a souligné @ Teresa-e-Junior, pactl est l'outil à utiliser:

Tout d'abord, nous pourrions vouloir obtenir les ID de nos éviers de sonorisation. Sur mon système, voici ce que j'obtiens:

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

L'évier 1 est actuellement mon évier par défaut.
Mais maintenant, je veux que tous mes flux actuels et futurs soient lus via HDMI (c.-à-d. Récepteur 0).

Il existe une commande pour définir le récepteur par défaut pour PulseAudio, mais cela ne semble pas avoir d'effet sur mon PC:

$ pacmd set-default-sink 0 #doesn't work on my PC :(

Au lieu de cela, de nouveaux flux semblent être connectés à l'évier sur lequel un flux y a été déplacé le plus récemment.

Disons donc à pactl de déplacer tous les flux en cours de lecture vers le puits 0. Nous devons d'abord les répertorier:

$ pactl list short sink-inputs
290     1       176     protocol-native.c       float32le 2ch 44100Hz
295     1       195     protocol-native.c       float32le 2ch 44100Hz

Ok, nous avons deux flux (ID 290 et 295) qui sont tous deux attachés au récepteur 1.
Déplaçons-les pour couler 0:

$ pactl move-sink-input 290 0
$ pactl move-sink-input 295 0

Donc, ça devrait être ça. Il ne nous reste plus qu'à créer un script qui fait le travail pour nous:

#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 <sinkId/sinkName>" >&2
    echo "Valid sinks:" >&2
    pactl list short sinks >&2
    exit 1
fi

newSink="$1"

pactl list short sink-inputs|while read stream; do
    streamId=$(echo $stream|cut '-d ' -f1)
    echo "moving stream $streamId"
    pactl move-sink-input "$streamId" "$newSink"
done

Vous pouvez l'appeler avec un ID récepteur ou un nom de récepteur comme paramètre (c'est-à-dire soit 0 ou quelque chose comme alsa_output.pci-0000_01_00.1.hdmi-surround).

Vous pouvez maintenant attacher ce script à un événement udev ou à un raccourci clavier.

58
mreithub

Les commandes suivantes sont utilisées pour manipuler le serveur de son PulseAudio:

pacmd - Used to reconfigure a PulseAudio sound server during runtime.
pactl - Used to control a running PulseAudio sound server.

Voici quelques exemples de leur fonctionnement.

pacmd list-sinks :: nom de la liste ou numéro d'index des puits possibles

pacmd set-default-sink [sinkname] :: définir le récepteur par défaut de sortie

pacmd set-default-source [sourcename] :: définir l'entrée par défaut

pacmd set-sink-volume [index] [volume] :: définir le volume du récepteur

pacmd set-source-volume index volume :: contrôle du volume plage 0 - 65536 (plus le nombre est bas, plus le volume est bas)

Ce ne sont que quelques-uns que j'ai retirés de la page wiki et man. Référence this pour des informations plus détaillées. Ou vous pouvez afficher les commandes --help ou man page.

Il existe également un outil en ligne de commande qui sert à cet effet. Son nom est ponymix . C'est un mélangeur en ligne de commande pour PulseAudio. Le lien fourni est vers le github des projets. Il est développé par un ami et collègue Arch Linux Trusted User/Developer. Si vous n'exécutez pas Arch, vous pouvez simplement le compiler à partir des sources en utilisant make et Sudo make install.

$ ponymix --help
    usage: ponymix [options] <command>... 
Options:
 -h, --help              display this help and exit    
 -c, --card CARD         target card (index or name)
 -d, --device DEVICE     target device (index or name)
 -t, --devtype TYPE      device type
 -N, --notify            use libnotify to announce volume changes
     --source            alias to -t source
     --input             alais to -t source
     --sink              alias to -t sink
     --output            alias to -t sink
     --sink-input        alias to -t sink-input
     --source-output     alias to -t source-output
Device Commands:
  help                   display this message
  defaults               list default devices (default command)
  set-default            set default device by ID
  list                   list available devices
  list-short             list available devices (short form)
  list-cards             list available cards
  list-cards-short       list available cards (short form)
  get-volume             get volume for device
  set-volume VALUE       set volume for device
  get-balance            get balance for device
  set-balance VALUE      set balance for device
  adj-balance VALUE      increase or decrease balance for device
  increase VALUE         increase volume
  decrease VALUE         decrease volume
  mute                   mute device
  unmute                 unmute device
  toggle                 toggle mute
  is-muted               check if muted
Application Commands:
  move DEVICE            move target device to DEVICE
  kill DEVICE            kill target DEVICE
Card Commands:
  list-profiles          list available profiles for a card
  list-profiles-short    list available profiles for a card(short form)
  get-profile            get active profile for card
  set-profile PROFILE    set profile for a card
10
cinelli

Sur mon ordinateur portable exécutant Fedora 20, la sortie HDMI n'est pas répertoriée en tant que puits dans le profil par défaut, mais en tant que profil différent.

Je n'ai qu'un seul évier comme celui-ci, une belle musique joue sur mes haut-parleurs d'ordinateur portable:

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

Si je lance pactl set-card-profile 0 output:hdmi-stereo puis de la bonne musique est jouée via HDMI. Je reçois:

$ pactl list short sinks
14  alsa_output.pci-0000_00_1b.0.hdmi-stereo    module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

Pour revenir à la valeur par défaut, je lance simplement pactl set-card-profile 0 output:analog-stereo+input:analog-stereo. Quoi qu'il en soit, la valeur par défaut est de nouveau là si je redémarre.

La liste des profils de ma carte se trouve quelque part sur pactl list cards production.

5
RubenCaro

En étendant la réponse acceptée par @cinelli, j'ai trouvé un script qui

  • bascule entre exactement deux récepteurs/périphériques de sortie qui doivent être définis dans le script,
  • bascule les flux ET le récepteur par défaut, donc les touches multimédias du clavier fonctionnent et
  • laisse mon module d'annulation d'écho intact.

Changez au besoin!

#!/bin/bash

# Small script to switch between two hardcoded sound output devices

# Set patterns for devices to be toggled. Have to match to second column
# in output of "pactl list short sinks".
# (Could also hardcode the full names, but this might be a little more robust)
TOGGLE1="Jabra_EVOLVE"
TOGGLE2="Generic_ThinkPad_Dock_USB"

# Discover which sink (output device) is active, and set up toggles
while read -r stream; do
  echo "$stream"
  if echo "$stream" | grep -q "RUNNING"; then
    currentSink=$(echo "$stream" | cut -f2)
  fi
  if echo "$stream" | grep -q "$TOGGLE1"; then
    toggle1Sink=$(echo "$stream" | cut -f2)
  fi
  if echo "$stream" | grep -q "$TOGGLE2"; then
    toggle2Sink=$(echo "$stream" | cut -f2)
  fi
done < <(pactl list short sinks)

# Set up where to switch to
if [ "$currentSink" = "$toggle1Sink" ]; then
  newSink=$toggle2Sink
else
  newSink=$toggle1Sink
fi

# Switch streams AND default sink
pactl list short sink-inputs|while read -r stream; do
    streamId=$(echo "$stream"|cut '-d ' -f1)
    # exclude echo cancellation module, but switch all other streams
    # You can, but don't have to remove if condition if no such module present
    if [ "$streamId" != "0" ]; then
      echo "moving stream $streamId"
      pactl move-sink-input "$streamId" "$newSink"
    fi;
    # Also switch default sink, so media control keys work correctly
    pactl set-default-sink "$newSink"
done
0
Thor