Wie ändere ich die pulseaudio sink während der Wiedergabe mit "pacmd set-default-sink"?


55

Ich muss den pulseaudio-Server eines aktuell wiedergegebenen Audiostreams umschalten.

Der Pulseaudio-Server ist mit IP 192.168.1.105 eingerichtet

$>cat /etc/pulse/default.pa
...
load-module module-esound-protocol-tcp auth-anonymous=1
load-module module-native-protocol-tcp auth-anonymous=1
load-module module-zeroconf-publish
...

Auf der Quellenseite spielt der VLC Media Player ein Lied ab.

Ich habe eine neue Tunnelspüle mit pulseaudio auf der Quellenseite erstellt.

pacmd load-module module-tunnel-sink server=192.168.1.105
pacmd set-default-sink 1

Während der Audiowiedergabe konnte der Server jedoch nicht sofort geändert werden. Erst nach dem Stoppen des Players und dem erneuten Abspielen ist es in Ordnung.

Ab "gnome-volume-control" oder "gnome-control-center sound" wird die Umschaltung der Ausgabegeräte sofort wirksam.

Wie kann ich festlegen, dass die Ausgabesenke während der Wiedergabe einer Audiodatei sofort von der Befehlszeile aus umgeschaltet wird?

Antworten:


83

PulseAudio pacmdist nicht in der Lage, die Standardsenken zu wechseln, während ein aktiver Stream zum Senken-Eingang vorliegt. Es gibt jedoch noch einen Weg, dies zu erreichen.

Ändern der Standardsenke über die Befehlszeile

Zuerst müssen wir die Indexnummer der Senken bestimmen, die wir wechseln möchten. Dies kann durch einen Anruf erfolgen:

pacmd list-sinks

Abhängig von unserem System erhalten Sie eine mehr oder weniger lange Liste von Waschbecken und Eigenschaften, auf die derzeit zugegriffen werden kann:

 >>> 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>

Das indexoder das name, was hier angegeben ist, wird benötigt, um die Senke über die Befehlszeile anzusprechen. Die aktuelle Standardsenke ist (hier 0) mit einem Sternchen markiert .

Um die Standardsenken von der Befehlszeile aus umschalten zu können, müssen wir möglicherweise die Wiederherstellung des Stream-Zielgeräts deaktivieren, indem Sie die entsprechende Zeile in /etc/pulse/default.paden folgenden Schritten bearbeiten :

load-module module-stream-restore restore_device=false

Um die Standardausgabesenke in Senke zu ändern, führen 1wir dann aus

pacmd set-default-sink 1

Sucess kann durch Öffnen des visualisiert werden Toneinstellungen Menü.

Einen Stream in eine andere Spüle verschieben

Das Ändern der Standardsenke, während ein aktiver Eingabestream auf einer bestimmten Senke abgespielt wird, hat keine Auswirkung . Dies sollte eher durch Verschieben dieses Eingangs in eine andere Senke erfolgen.

pacmd list-sink-inputs

teilt uns den Index des Eingabestreams mit

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

Wir wissen jetzt, dass wir den Eingabestream durch Aufrufen 5auf sink verschieben möchten1

pacmd move-sink-input 5 1

oder zurück zum sinken 0wenn wir wollen. Dies erfolgt sofort, ohne dass die Wiedergabe gestoppt werden muss.

Ändern der Standardsenke während des Spielens

Natürlich können wir diese beiden Befehle kombinieren, um die Standardsenken während der Wiedergabe sofort umzuschalten, z. B. mit

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

Ein Nachteil dieser Methode ist, dass sich der Eingabestream-Index jedes Mal ändert, wenn der Musik-Player angehalten und neu gestartet wird. Wir müssen also immer den aktuellen Stream-Index herausfinden, bevor wir mit der Befehlszeile wechseln können.


Sie können eine Senke durch seinen Index oder seinen Namen verweisen pactl list short sinks> 4 bluez_sink.FC_A8_9A_2C_EB_0B module-bluez5-device.c s16le 1ch 8000Hz IDLEjetzt Referenz nur den Namenpactl set-default-sink bluez_sink.FC_A8_9A_2C_EB_0B
Leif Liddy

@LeifLiddy: Danke für den Hinweis. In neueren Versionen von Pulseaudio können Sie zwar auf den Namen einer Senke verweisen, set-default-sinkSie benötigen jedoch weiterhin die Indexnummer move-sink-input.
Takkat

Und wenn doch 0 sink input(s) available.? Aber dieser beschissene Flash-Player spielt immer noch Audio ab?
Zhigalin

Und ich sehe Flash-Player in der client(s) logged inSektionpacmd list
Zhigalin

@ Zhigalin Flash ist auf meinen Systemen schon lange tot, daher kann ich nicht wirklich sagen, dass es direkt über ALSA abgespielt werden kann.
Takkat

27

Ich habe ein einfaches Skript geschrieben, um alle Sink-Eingaben automatisch zu verschieben.

Verwendungszweck: ./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

1
Genial! Ich habe dies für meinen eigenen Gebrauch etwas erweitert: Ich wollte ein Symbol in meiner Taskleiste, das zwischen zwei Audiokarten umschaltet. Ich habe ein winziges Skript in Ruby geschrieben, um die aktuelle Senke zu ermitteln, und dieses Shell-Skript aufgerufen, um die Änderung vorzunehmen ( pastebin.com/xb3i2ejW ). Danach habe ich beide Skripte in ~ / bin abgelegt und ein KDE-Symbol angepasst, um das Ruby-Skript auszuführen. Dies könnte eleganter oder vollständig in Shell-Skript erfolgen, aber es funktioniert für mich.
Pathogen

2
Danke dafür. Hier ist eine Version, die auf die letzte (? - Ich habe nur zwei) nicht verwendete Ausgabe umschaltet : pastebin.com/raw/sidH7QPb, dh die Ausgabe wird umgeschaltet, was für die Zuordnung zu einem Hotkey geeignet ist.
Julian

4

Verbesserte Version des @ Gaco- Skripts

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

Meine Runtime-Kopie ist auf Github und beinhaltet auch die automatische Umschaltung des Master-Kanals fürkmix



2

Ich habe Sachen von verschiedenen Orten zusammengeschustert und mir dieses Skript ausgedacht, um eine Bluetooth-JAMBOX einzurichten, nachdem sie gekoppelt wurde. Ihr MAC wird natürlich anders sein. Da ich die JAMBOX-Lautstärke über die Clementine-App steuere, funktionieren 130% der Lautstärke in meinem Fall am besten. Vielleicht möchten Sie dies zusammen mit der rhythmbox.png ändern (es war das einzige Sprecherbild, das ich auf meinem Computer finden konnte). Die Fehlerprüfung ist rudimentär, funktioniert aber ziemlich zuverlässig. Ich habe dies in einem Desktop-Launcher für die Bequemlichkeit auf einem ASUS-Netbook abgelegt.

#!/bin/bash
# setjambox connection setup
# Find the particulars of your environment with 'pactl list sinks'
# This script uses the sink name instead of the index number
# You also need libnotify-bin to run this script

# Enter the bluetooth MAC address of your device here
MAC=00:21:3C:9F:19:AD

# Make ready
# Convert device address per pulseaudio standards
DEV=$(echo $MAC|tr ':' '_')
TITLE="JAMBOX $MAC"
CONNECTED="Audio connection updated."
PROBLEM="Unable to update settings."
JBLOGO=/usr/share/icons/hicolor/48x48/apps/rhythmbox.png

# And go

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

pactl set-default-sink bluez_sink.$DEV
pactl set-card-profile bluez_card.$DEV a2dp
pactl set-sink-volume  bluez_sink.$DEV 130%

if [ $? -eq 0 ]
then
   notify-send -i $JBLOGO -t 3000 "$TITLE" "$CONNECTED" 
else
   notify-send -i gtk-dialog-warning -t 3000 "$TITLE" "$PROBLEM"
fi

+1 für die Verwendung pactl list short. Sie können die folgende Zeile vereinfachen, indem Sie den Schnitt direkt danach ausführen: Funktioniert pactl list short sink-inputs | cut -f1 | while read streamIdfür mich.
Bodo

1

CIRCLE-TOGGLE-SPÜLEN.

Das Gaco-Skript mit nur einer weiteren Zeile zum Umschalten zwischen den verfügbaren Senken.

#!/bin/bash 

new_sink=$(pacmd list-sinks | grep index | tee /dev/stdout | grep -m1 -A1 "* index" | tail -1 | cut -c12-)

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

done

toll, einfach und skalierbar!
Paul Bastian

1

Und hier ist ein Skript, das auch zwischen Senken umschaltet:

http://marginalhacks.com/index.0.html#pulse-switch-out

Hier ist das Skript unten:

#!/usr/bin/ruby
# Filename: pulse-switch-out
# Author:   David Ljung Madison <DaveSource.com>
# See License:  http://MarginalHacks.com/License/
# Description:  Switch pulse audio output (sink) using pacmd

PACMD = %w(pacmd)

##################################################
# Usage
##################################################
def fatal(*msg)
    msg.each { |m| $stderr.puts "[#{$0.sub(/.*\//,'')}] ERROR: #{m}" }
    exit(-1);
end

def usage(*msg)
    msg.each { |m| $stderr.puts "ERROR: #{m}" }
    $stderr.puts <<-USAGE

Usage:  #{$0.sub(/.*\//,'')} [sink]
  Switch sound playback device for ALSA/pulseaudio

    [sink]   Specify sink number to use (see 'pacmd list-sinks')

    USAGE
    exit -1;
end

def parseArgs
    opt = Hash.new
    loop {
        if (arg=ARGV.shift)==nil then break
        elsif arg == '-h' then usage
        elsif arg == '-?' then usage
        #elsif arg == '-arg' then opt[:arg] = true
        elsif arg =~ /^(\d)$/ then opt[:sink] = arg.to_i
        else
            usage("Unknown arg [#{arg}]")
        end
    }

    opt
end

# Unfortunately you can't return or break from the yield without leaving
# the pipe open, maybe use some sort of ensure and figure out how to close?
def pipe(cmd)
        # This is leaving files open
    #IO.popen(cmd.join(' ')).each { |l|
    a = `#{cmd.join(' ')}`
    ret = $?
    a.split("\n").each { |l|
        yield l
    }
    $?
end

def getSinks(ins=false)
    cmd = PACMD.dup
    cmd.push(ins ? 'list-sink-inputs' : 'list-sinks')
    curr = nil
    sinks = Array.new
    pipe(cmd) { |l|
        next unless l=~/\s*(\*)?\s*index:\s+(\d+)/
        i = $2.to_i
        sinks.push(i)
        curr = i if $1
    }
    return sinks,curr
end

##################################################
# Main code
##################################################
def main
    opt = parseArgs

    sinks,curr = getSinks

    usage("No sinks found?") if sinks.empty?
    usage("Only one sink found") if sinks.size==1

    if opt[:sink]
        usage("Unknown sink [#{opt[:sink]}] (out of #{sinks.join(' ')})") unless sinks.index(opt[:sink])
    else
        # Find next sink after curr
        opt[:sink] = sinks[0]
        sinks.each { |s|
            next unless s>curr
            opt[:sink] = s
            break
        }
    end

    # Set default sink
## For some reason this doesn't change the behavior of new apps.
    puts "Set sink: #{opt[:sink]}"
    system("#{PACMD} set-default-sink #{opt[:sink]} > /dev/null")
    usage("Couldn't set default sink [#{opt[:sink]}]") unless $?==0

    # And move all sink-inputs to the new sink
    ins,ignore = getSinks(true)
    ins.each { |i|
        puts "Move playback #{i} to sink #{opt[:sink]}"
        system("#{PACMD} move-sink-input #{i} #{opt[:sink]} > /dev/null")
        usage("Couldn't move playback #{i} to sink [#{opt[:sink]}]") unless $?==0
    }
end
main

1
Willkommen bei Ask Ubuntu! Während dies theoretisch die Frage beantworten mag, wäre es vorzuziehen , die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen.
ζ--

Dies bedeutet jedoch leider, dass das Skript hier nicht aktualisiert wird, es sei denn, ich erinnere mich, dass es hier ist. Als Beispiel hat Ruby die Art und Weise geändert, wie .each für Zeichenfolgen (im Backtick-Teil) behandelt wird, sodass ich Zeile 53 oben aktualisieren musste. Oder laden Sie einfach das Skript herunter, um sicherzustellen, dass es auf dem neuesten Stand ist.
David Ljung Madison Stellar

1

Basierend auf Gacos Antwort habe ich es ein wenig für meinen persönlichen Gebrauch umgeschrieben. Vielleicht findet es jemand nützlich. Hiermit können Sie meine USB-Lautsprecher und das USB-Gaming-Headset umschalten.

#!/bin/bash

# get list of sinks/cards (for settings CARD1/CARD2)
# pacmd list-sinks | awk '/name:/ {print $0};' | awk '{ print $2}' | sed 's/<//g; s/>//g'

CARD1="alsa_output.usb-C-Media_INC._C-Media_USB_Audio-00"
CARD2="alsa_output.usb-Kingston_HyperX_Virtual_Surround_Sound_00000000-00"

CURRENT_SINK=$(pacmd stat | awk -F": " '/^Default sink name: /{print $2}' | awk 'BEGIN{FS=OFS="."} NF--' | sed 's/alsa_output/alsa_output/g')


function setCard() {

  if [ "$CURRENT_SINK" == "$1" ]
   then
     echo "Already using this Sink"
     exit 1
  fi

  NEW_SINK=$(pacmd list-sinks | awk '/index:/ {print $1 $2 $3} /name:/ {print $0};' | grep -m1 -B1 $1 | grep index | awk '{print $1}' | cut -d ":" -f2)
  SINK=$(pacmd set-default-sink $NEW_SINK)
  INPUT=$(pacmd list-sink-inputs | grep index | awk '{print $2}')

  pacmd move-sink-input $INPUT $NEW_SINK
  echo "Moving input: $INPUT to sink: $NEW_SINK";
  echo "Setting default sink to: $NEW_SINK";

  notify-send --urgency=low "Audio Switching" "SINK: $NEW_SINK"
}

function toggleSinks() {
  if [ "$CURRENT_SINK" == "$CARD1" ]
    then
      setCard $CARD2
    else
      setCard $CARD1
    fi
}


function showHelp() {
  echo "------------------------------------"
  echo "AUDIO SINK SWITCHER"
  echo " "
  echo "$0 [options]"
  echo " "
  echo "options:"
  echo "-h  --help        What you are looking at.."
  echo "-g, --gaming      Sets Gaming headset as output device"
  echo "-s, --speakers    Sets Speakers as output device"
  echo "-t, --toggle      Toggles the different output devices"
  echo " "
  echo "------------------------------------"
}

# check args length
if [ $# -eq 0 ]
  then
    echo "Toggling output devices (Speakers/Headset)"
    toggleSinks
fi


# arg options
while test $# -gt 0; do
    case "$1" in

                -h|--help)
                        showHelp
                        exit 1
                        ;;

                -g|--gaming)
                        setCard $CARD2
                        exit 1
                        ;;

                -s|--speakers)
                        setCard $CARD1
                        exit 1
                        ;;

                -t|--toggle)
                        toggleSinks
                        echo "Toggling output devices (Speakers/Headset)"
                        exit 1
                        ;;
                 *)
                        showHelp
                        exit 1
                        ;;
    esac
done

0

Ich denke, es gibt eine weitere erwähnenswerte Option, die auf der offiziellen Seite für häufig gestellte Fragen zu PulseAudio unter freedesktop.org verfügbar ist . Unter folgendem Titel:

Wie ändere ich die Standard-Soundkarte und verschiebe alle Anwendungen?

Sie bieten dazu das folgende Skript an:

#/bin/bash
# paswitch 2011-02-02 by Ng Oon-Ee <ngoonee@gmail.com>
# I can't remember where I found this script, can't locate the original author.
# Please inform me if you know, so that I can give proper attribution.
# CHANGES: Added auto-move all inputs to new default sound card.
# WAS: Pulse Audio Sound Card Switcher v1.0 2010-01-13
#   Switches between soundcards when run. All streams are moved to the new default sound-card.

# $totalsc: Number of sound cards available
totalsc=$(pacmd "list-sinks" | grep card: | wc -l) # total of sound cards: $totalsc
if [ $totalsc -le 1 ]; then # Check whether there are actually multiple cards available
  notify-send -u critical -t 5000 "Nothing to switch, system only has one sound card."
  exit
fi
# $scindex: The Pulseaudio index of the current default sound card
scindex=$(pacmd list-sinks | awk '$1 == "*" && $2 == "index:" {print $3}')
# $cards: A list of card Pulseaudio indexes
cards=$(pacmd list-sinks | sed 's|*||' | awk '$1 == "index:" {print $2}')
PICKNEXTCARD=1 # Is true when the previous card is default
count=0 # count of number of iterations
for CARD in $cards; do
  if [ $PICKNEXTCARD == 1 ]; then
# $nextsc: The pulseaudio index of the next sound card (to be switched to)
    nextsc=$CARD
    PICKNEXTCARD=0
# $nextind: The numerical index (1 to totalsc) of the next card
    nextind=$count
  fi
  if [ $CARD == $scindex ]; then # Choose the next card as default
    PICKNEXTCARD=1
  fi
  count=$((count+1))
done
pacmd "set-default-sink $nextsc" # switch default sound card to next

# $inputs: A list of currently playing inputs
inputs=$(pacmd list-sink-inputs | awk '$1 == "index:" {print $2}')
for INPUT in $inputs; do # Move all current inputs to the new default sound card
  pacmd move-sink-input $INPUT $nextsc
done
# $nextscdec: The device.description of the new default sound card
# NOTE: This is the most likely thing to break in future, the awk lines may need playing around with
nextscdesc=$(pacmd list-sinks | awk '$1 == "device.description" {print substr($0,5+length($1 $2))}' \
                         | sed 's|"||g' | awk -F"," 'NR==v1{print$0}' v1=$((nextind+1)))
notify-send "Default sound-card changed to $nextscdesc"
exit
# Below text was from original author and remains unaltered
# CC BY - creative commons
# Thanks God for help :) and guys lhunath, geirha, Tramp and others from irc #bash on freenode.net

0

Ich habe @mpapis an ein einfaches "toggle sink0 oder sink1" angepasst, wenn es ausgeführt wird:

#!/bin/bash
SINK_INDEX1=0
SINK_INDEX2=1
ACTIVE_SINK=$(pacmd list-sinks | grep '* index:' | grep -o '[0-9]*')
if [ "$ACTIVE_SINK" = $SINK_INDEX1 ] ; then
    pacmd set-default-sink $SINK_INDEX2
    pacmd list-sink-inputs | awk '/index:/{print $2}' | xargs -r -I{} pacmd move-sink-input {} $SINK_INDEX2
else 
    pacmd set-default-sink $SINK_INDEX1
    pacmd list-sink-inputs | awk '/index:/{print $2}' | xargs -r -I{} pacmd move-sink-input {} $SINK_INDEX1
fi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.