How to change pulseaudio sink with "pacmd set-default-sink" during playback?

PulseAudio pacmd is not capable of switching the default sinks while there is an actively playing stream to the sink input. However there is a way to still achieve this.

Changing default sink from command line

First we need to determine the index number of the sinks we want to switch. This can be done by calling:

pacmd list-sinks

Depending on our system this will give you a more or less lengthy list of sinks and properties that are at present accessible:

 >>> 2 sink(s) available.
      * index: 0
            name: <alsa_output.pci-0000_01_00.1.hdmi-stereo-extra1>
            driver: <module-alsa-card.c>
    :
    :
        index: 1
            name: <alsa_output.pci-0000_00_14.2.analog-stereo>
            driver: <module-alsa-card.c>

The index or the name given here is what we need for adressing the sink by command line. The present default sink is marked with an asterix (here 0).

To be able to switch the default sinks from command line we may need to disable stream target device restore by editing the corresponing line in /etc/pulse/default.pa to:

load-module module-stream-restore restore_device=false

To change the default output sink to sink 1 we then run

pacmd set-default-sink 1

Sucess can be visualized by opening the Sound Settings menu.

Moving a stream to another sink

Changing the default sink while we have an active input stream playing to a given sink has no effect. This should rather be done by moving this input to another sink.

pacmd list-sink-inputs

will tell us the index of the input stream

>>> 1 sink input(s) available.
    index: 5
    driver: <protocol-native.c>

We now know that we want to move the input stream 5 to sink 1 by calling

pacmd move-sink-input 5 1

or back to sink 0 if we like. This will be done immediately without the need of stopping playback.

Changing default sink while playing

Of course we can combine those two commands to immediately switch default sinks during playback e.g. with

pacmd set-default-sink 1 & pacmd move-sink-input 5 1

A drawback of this method is that the input stream index changes every time we stop and restart the music player. So we always have to find out the current stream index before we can switch using the commmand line.


I have written a simple script to move all the sink-inputs automatically.

Usage: ./movesinks.sh <sink number>

#!/bin/bash 
echo "Setting default sink to: $1";
pacmd set-default-sink $1
pacmd list-sink-inputs | grep index | while read line
do
echo "Moving input: ";
echo $line | cut -f2 -d' ';
echo "to sink: $1";
pacmd move-sink-input `echo $line | cut -f2 -d' '` $1

done

Improved version of @Gaco script

#!/usr/bin/env bash

case "${1:-}" in
  (""|list)
    pacmd list-sinks |
      grep -E 'index:|name:'
    ;;
  ([0-9]*)
    echo switching default
    pacmd set-default-sink $1 ||
      echo failed
    echo switching applications
    pacmd list-sink-inputs |
      awk '/index:/{print $2}' |
      xargs -r -I{} pacmd move-sink-input {} $1 ||
        echo failed
    ;;
  (*)
    echo "Usage: $0 [|list|<sink name to switch to>]"
    ;;
esac

my runtime copy is on github and it includes also automated switching of Master channel for kmix

Tags:

Pulseaudio