Как изменить приемник pulseaudio с “pacmd приемник по умолчанию набора” во время воспроизведения?

Я должен переключить 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 Media Player играет песню.

Я создал новый туннельный приемник с pulseaudio на исходной стороне.

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

Но при проигрывании аудио сервер не мог быть сразу изменен. Только после остановки плеера и воспроизведения, это в порядке.

От "регулятора громкости гнома" или "звук центра управления гнома" переключение устройств вывода сразу применяется.

Как я могу применить переключение выходного приемника сразу из командной строки во время воспроизведения звукового файла?

55
задан 26 October 2011 в 01:08

10 ответов

PulseAudio pacmd не способно к переключению приемников по умолчанию, в то время как существует активно поток проигрывания к входу приемника. Однако существует способ все еще достигнуть этого.

Изменение приемника по умолчанию из командной строки

Сначала мы должны определить индекс приемников, которые мы хотим переключить. Это может быть сделано путем вызова:

pacmd list-sinks

В зависимости от нашей системы это даст Вам более или менее длинный список приемников и свойств, которые в настоящее время доступны:

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

index или name данный здесь то, что нам нужен для адресации приемник командной строкой. Существующий приемник по умолчанию отмечен с Астериксом (здесь 0).

Чтобы смочь переключить приемники по умолчанию с командной строки, мы, возможно, должны отключить потоковое восстановление целевого устройства путем редактирования corresponing строки в /etc/pulse/default.pa кому:

load-module module-stream-restore restore_device=false

Изменить выходной приемник по умолчанию для снижения 1 мы затем работаем

pacmd set-default-sink 1

Sucess может визуализироваться путем открытия Sound Settings menu.

Перемещение потока к другому приемнику

Изменение приемника по умолчанию, в то время как у нас есть активный входной поток, подыгрывающий данному приемнику, не имеет никакого эффекта. Это должно скорее быть сделано путем перемещения этого входа в другой приемник.

pacmd list-sink-inputs

скажет нам индекс входного потока

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

Мы теперь знаем, что хотим переместить входной поток 5 снизиться 1 путем вызова

pacmd move-sink-input 5 1

или назад снизиться 0 если нам нравится. Это будет сразу сделано без потребности останавливающегося воспроизведения.

Изменение значения по умолчанию снижается при проигрывании

Конечно, мы можем объединить те две команды для непосредственного переключения приемников по умолчанию во время воспроизведения, например, с

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

Недостаток этого метода состоит в том, что входной потоковый индекс изменяется каждый раз, когда мы останавливаем и перезапускаем аудиоплеер. Таким образом, мы всегда должны узнавать текущий потоковый индекс, прежде чем мы сможем переключить использование строки команды.

83
ответ дан 26 October 2011 в 01:08

Я написал простой скрипт для автоматического перемещения всех входов приемника.

Использование: ./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
0
ответ дан 26 October 2011 в 01:08

Улучшенная версия @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

моя копия во время выполнения находится на GitHub, и это включает также автоматизированное переключение Основного канала для kmix

4
ответ дан 26 October 2011 в 01:08

Существует скрипт ruby ​​(который я изначально разветвлял и переписывал) , который позволяет вам изменять приемники по умолчанию, громкость и состояние отключения звука из командной строки.

0
ответ дан 26 October 2011 в 01:08

Я собрал воедино материал из нескольких разных мест и придумал этот скрипт, чтобы настроить Bluetooth JAMBOX после его сопряжения. Ваш MAC будет другим, конечно. Поскольку я контролирую громкость JAMBOX с помощью приложения Clementine, 130% громкости лучше всего работает в моем случае. Возможно, вы захотите изменить это, наряду с rhythmbox.png (это была единственная картинка динамика, которую я смог найти на своем компьютере). Проверка ошибок является элементарной, но работает довольно надежно. Я поместил это в настольный лаунчер для удобства на нетбуке ASUS.

#!/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
0
ответ дан 26 October 2011 в 01:08

КРУЖЕВНЫЕ МОЙКИ.

Скрипт 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
0
ответ дан 26 October 2011 в 01:08

На основе ответа 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
1
ответ дан 26 October 2011 в 01:08

Я думаю, что существует еще одна опция, которую стоит упомянуть, и это доступно на уровне официальной страницы для FAQ о PulseAudio по freedesktop.org. В соответствии со следующим Заголовком:

Как я переключаю звуковую карту по умолчанию, перемещая все приложения?

Они предоставляют следующий сценарий, чтобы сделать так:

#/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
ответ дан 26 October 2011 в 01:08

Я настроил @mpapis для простого «переключения раковины0 или раковины1» при запуске:

#!/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
0
ответ дан 26 October 2011 в 01:08

И вот сценарий, который переключится между приемниками также:

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

Вот сценарий ниже:

#!/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
ответ дан 26 October 2011 в 01:08

Другие вопросы по тегам:

Похожие вопросы: