如何在播放期间使用“pacmd set-default-sink”更改pulseaudio sink?

我需要切换当前正在播放的音频流的pulseaudio服务器。

Pulseaudio服务器设置为IP 192.168.1.105

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

在源端,VLC媒体播放器正在播放歌曲。

我在源端创建了一个带有pulseaudio的新隧道接收器。

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

但在播放音频时,服务器无法立即更改。 只有在停止播放器并重放后,才可以。

从“gnome-volume-control”或“gnome-control-center sound”立即应用输出设备的切换。

如何在播放声音文件时立即从命令行应用切换输出接收器?

当有一个主动播放流到接收器输入时,PulseAudio pacmd无法切换默认接收器。 但是有一种方法可以实现这一目标。

从命令行更改默认接收器

首先,我们需要确定要切换的接收器的索引号。 这可以通过调用:

 pacmd list-sinks 

根据我们的系统,这将为您提供或多或少冗长的接收器和属性列表,目前可访问:

  >>> 2 sink(s) available. * index: 0 name:  driver:  : : index: 1 name:  driver:  

这里给出的indexname是我们通过命令行来解决接收器所需要的。 当前的默认接收器标有星号(此处为0 )。

为了能够从命令行切换默认接收器,我们可能需要通过编辑/etc/pulse/default.pa的对应线来禁用流目标设备恢复

 load-module module-stream-restore restore_device=false 

要将默认输出接收器更改为接收器1我们将运行

 pacmd set-default-sink 1 

通过打开“ 声音设置”菜单可以显示成功。

将流移动到另一个接收器

当我们将活动输入流播放到给定接收器时更改默认接收器无效 。 这应该通过将此输入移动到另一个接收器来完成。

 pacmd list-sink-inputs 

将告诉我们输入流的索引

 >>> 1 sink input(s) available. index: 5 driver:  

我们现在知道我们想通过调用将输入流5移动到接收器1

 pacmd move-sink-input 5 1 

如果我们愿意,可以回到0 。 这将立即完成,无需停止播放。

播放时更改默认接收器

当然,我们可以将这两个命令组合起来,以便在播放期间立即切换默认接收器,例如

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

这种方法的缺点是每次我们停止并重启音乐播放器时输入流索引都会改变 。 所以我们总是要在使用命令行切换之前找出当前的流索引。

我编写了一个简单的脚本来自动移动所有接收器输入。

用法: ./movesinks.sh

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

有一个ruby脚本(我最初分叉并重写了部分) ,允许您从命令行更改默认接收器,音量和静音状态 。

改进版的@Gaco 脚本

 #!/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|]" ;; esac 

我的运行时副本在github上 ,它还包括自动切换kmix主通道

我拼凑了几个不同的地方的东西,并提出这个脚本,一旦配对就设置蓝牙JAMBOX。 你的MAC当然会有所不同。 由于我通过Clementine应用程序控制JAMBOX音量,因此在我的情况下130%音量最佳。 你可能想要改变它,以及rhythmbox.png(这是我在电脑上找到的唯一的扬声器图片)。 错误检查是基本的,但工作非常可靠。 为了方便起见,我把它放在桌面发射器上,用于华硕上网本。

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

这里有一个脚本,可以在接收器之间切换:

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

这是下面的脚本:

 #!/usr/bin/ruby # Filename: pulse-switch-out # Author: David Ljung Madison  # 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 

CIRCLE-TOGGLE SINKS。

Gaco脚本只有一行可循环切换可用的接收器。

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

我认为还有一个值得一提的选项,可以在freedesktop.org上 关于PulseAudio的常见问题解答的官方页面上找到。 在以下标题下:

如何切换默认声卡,移动所有应用程序?

他们提供以下脚本:

 #/bin/bash # paswitch 2011-02-02 by Ng Oon-Ee  # 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 

运行时,我将@mpapis改为简单的“toggle sink0或sink1”:

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