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

was*_*sak 70 pulseaudio

我需要切换当前播放的音频流的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
...
Run Code Online (Sandbox Code Playgroud)

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

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

pacmd load-module module-tunnel-sink server=192.168.1.105
pacmd set-default-sink 1
Run Code Online (Sandbox Code Playgroud)

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

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

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

Tak*_*kat 107

PulseAudiopacmd无法在接收器输入端有正在播放的流时切换默认接收器。但是,仍然有一种方法可以实现这一目标。

从命令行更改默认接收器

首先我们需要确定我们要切换的sink的索引号。这可以通过调用来完成:

pacmd list-sinks
Run Code Online (Sandbox Code Playgroud)

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

 >>> 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>
Run Code Online (Sandbox Code Playgroud)

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

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

load-module module-stream-restore restore_device=false
Run Code Online (Sandbox Code Playgroud)

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

pacmd set-default-sink 1
Run Code Online (Sandbox Code Playgroud)

通过打开声音设置菜单可以看到成功。

将流移动到另一个接收器

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

pacmd list-sink-inputs
Run Code Online (Sandbox Code Playgroud)

会告诉我们输入流的索引

>>> 1 sink input(s) available.
    index: 5
    driver: <protocol-native.c>
Run Code Online (Sandbox Code Playgroud)

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

pacmd move-sink-input 5 1
Run Code Online (Sandbox Code Playgroud)

0如果我们愿意,或者回到沉没。这将立即完成,无需停止播放。

播放时更改默认接收器

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

pacmd set-default-sink 1 & pacmd move-sink-input 5 1
Run Code Online (Sandbox Code Playgroud)

这种方法的一个缺点是每次我们停止和重新启动音乐播放器时,输入流索引都会发生变化。所以我们总是要找出当前的流索引,然后才能使用命令行进行切换。


小智 33

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

用法: ./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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你。这是一个切换到最后一个(? - 我只有两个)未使用输出的版本:http://pastebin.com/raw/sidH7QPb 即它切换输出,适合映射到热键。 (2认同)

mpa*_*pis 8

@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|<sink name to switch to>]"
    ;;
esac
Run Code Online (Sandbox Code Playgroud)

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


小智 5

圆形切换水槽。

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
Run Code Online (Sandbox Code Playgroud)


小智 5

根据 Gaco 的回答,我对它进行了一些重写以供个人使用。也许有人觉得它有用。它用于切换我的 USB 扬声器和 USB 游戏耳机。

#!/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
Run Code Online (Sandbox Code Playgroud)