web-dev-qa-db-ja.com

シェルからのPulseAudio入力/出力を変更しますか?

スピーカーと通常のマイクに加えて、時々使用するNiceワイヤレスヘッドフォンのセットを持っています。

ある入力ソースと出力ソースを切り替えるスクリプトを記述したいと思います。基本的には、ヘッドフォンとスピーカー+マイクを切り替えます。

これを変更したいのですが:

...この:

2つの入力と出力の間の転送をスクリプト化する方法はありますか?基本的に私はこのようなものを探しています:

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

これをスクリプト化する方法はありますか?

40
Naftuli Kay

@ Teresa-e-Juniorが指摘したように、pactlは使用するツールです。

まず最初に、PAシンクのIDを取得する必要があります。私のシステムでは、これは私が得るものです:

$ 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

シンク1は現在、デフォルトのシンクです。
しかし、現在および将来のすべてのストリームをHDMI経由で再生したい(つまり、シンク0)。

PulseAudioのデフォルトシンクを設定するコマンドがありますが、私のPCには影響がないようです。

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

代わりに、新しいストリームは、ストリームが最後に移動されたシンクに接続されているようです。

そこで、現在再生中のすべてのストリームを0に移動するようにpactlに指示しましょう。最初にそれらをリストする必要があります:

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

どちらもシンク1に接続されている2つのストリーム(ID 290と295)があります。
シンクに移動しましょう0

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

だから、それはそれであるはずです。これで、機能するスクリプトを作成する必要があります。

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

シンクIDまたはシンク名をパラメーターとして使用して呼び出すことができます(つまり、0またはalsa_output.pci-0000_01_00.1.hdmi-surroundのようなもの)。

これで、このスクリプトをudevイベントまたはキーショートカットにアタッチできます。

58
mreithub

以下のコマンドを使用して、PulseAudioサウンドサーバーを操作します。

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

これらがどのように機能するかの例をいくつか示します。

pacmd list-sinks ::リスト名またはインデックス番号の可能性シンク

pacmd set-default-sink [sinkname] ::デフォルト出力シンクを設定します

pacmd set-default-source [sourcename] ::デフォルトの入力を設定します

pacmd set-sink-volume [index] [volume] ::シンクを設定しますvolume

pacmd set-source-volume index volume ::ボリュームコントロール範囲0〜65536(数値が小さいほどボリュームが小さい)

これらは、私がwiki&manページから引き出したほんの一部です。詳細は this を参照してください。または、コマンド--helpまたはmanページを表示することもできます。

この目的に役立つコマンドラインツールも既に存在しています。名前は ponymix です。これはPulseAudioのコマンドラインミキサーです。提供されているリンクは、プロジェクトgithubへのリンクです。友人であり仲間のArch Linux Trusted User/Developerによって開発されました。 Archを実行していない場合は、makeおよび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

Fedora 20を実行している私のラップトップでは、HDMI出力は、デフォルトのプロファイルではsinkとしてではなく、別のprofile自体としてリストされています。

このようなシンクは1つしかありません。ラップトップのスピーカーで再生する素敵な音楽:

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

pactl set-card-profile 0 output:hdmi-stereoを実行すると、素敵な音楽がHDMI経由で再生されます。私は得ます:

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

デフォルトに戻すには、pactl set-card-profile 0 output:analog-stereo+input:analog-stereoを実行します。どちらにしても、再起動するとデフォルトが再び表示されます。

私のカードのプロファイルのリストはpactl list cards出力のどこかにあります。

5
RubenCaro

@cinelliの承認済みの回答を拡張して、次のようなスクリプトを作成しました。

  • スクリプトで定義する必要がある正確に2つのシンク/出力デバイスを切り替えます。
  • ストリームとデフォルトのシンクを切り替え、キーボードのメディアキーが機能し、
  • エコーキャンセレーションモジュールはそのままにしておきます。

必要に応じて交換してください!

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