Change PulseAudio Input/Output from Shell?
As @Teresa-e-Junior pointed out pactl
is the tool to use:
First of all we might want to get the IDs of our PA sinks. On my system this is what I get:
$ 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
Sink 1 is currently my default sink.
But now I want all my current and future streams to be played via HDMI (i.e. sink 0).
There is a command to set the default sink for PulseAudio, but it doesn't seem to have any effect on my PC:
$ pacmd set-default-sink 0 #doesn't work on my PC :(
Instead, new streams seem to be connected to the sink that had a stream moved to it most recently.
So let's tell pactl to move all currently playing streams to sink 0
.
We'll first need to list them:
$ pactl list short sink-inputs
290 1 176 protocol-native.c float32le 2ch 44100Hz
295 1 195 protocol-native.c float32le 2ch 44100Hz
Ok, we've got two streams (IDs 290 and 295) that are both attached to sink 1
.
Let's move them to sink 0
:
$ pactl move-sink-input 290 0
$ pactl move-sink-input 295 0
So, that should be it. Now we just have to make a script that does the work for us:
#!/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
You can call it with either a sink ID or a sink name as parameter (i.e. either 0
or something like alsa_output.pci-0000_01_00.1.hdmi-surround
).
Now you could attach this script to a udev event or key shortcut.
The following commands can be used to manipulate the PulseAudio sound server:
pacmd - Used to reconfigure a PulseAudio sound server during runtime.
pactl - Used to control a running PulseAudio sound server.
Here are some examples of how they function:
pacmd list-sinks
:: list name or index number of possible sinks
pacmd set-default-sink [sinkname]
:: set the default output sink
pacmd set-default-source [sourcename]
:: set the default input
pacmd set-sink-volume [index] [volume]
:: set the sink volume
pacmd set-source-volume index volume
:: volume control range 0 - 65536 (the lower the number the lower the volume)
These are only a few that I've pulled out of the wiki & man page. Reference this for more detailed information. Or you can view either commands --help
or man
page.
There is also a command line tool already out there that serves this purpose. It's name is ponymix. It's a command line mixer for PulseAudio. The link provided is to the projects github. It's developed by a friend and fellow Arch Linux Trusted User / Developer. If you're not running Arch you could just compile it from source using make
and 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
On my laptop running Fedora 20, HDMI output is not listed as a sink in the default profile, but as a different profile itself.
I have only 1 sink like this, nice music playing on my laptop speakers:
$ pactl list short sinks
8 alsa_output.pci-0000_00_1b.0.analog-stereo module-alsa-card.c s16le 2ch 44100Hz RUNNING
If I run pactl set-card-profile 0 output:hdmi-stereo
then nice music is playing through HDMI. I get:
$ pactl list short sinks
14 alsa_output.pci-0000_00_1b.0.hdmi-stereo module-alsa-card.c s16le 2ch 44100Hz RUNNING
To get back to default I just run pactl set-card-profile 0 output:analog-stereo+input:analog-stereo
. Either way the default is there again if I reboot.
The list of profiles for my card is somewhere on pactl list cards
output.