Я должен переключить 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
Но при проигрывании аудио сервер не мог быть сразу изменен. Только после остановки плеера и воспроизведения, это в порядке.
От "регулятора громкости гнома" или "звук центра управления гнома" переключение устройств вывода сразу применяется.
Как я могу применить переключение выходного приемника сразу из командной строки во время воспроизведения звукового файла?
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
Недостаток этого метода состоит в том, что входной потоковый индекс изменяется каждый раз, когда мы останавливаем и перезапускаем аудиоплеер. Таким образом, мы всегда должны узнавать текущий потоковый индекс, прежде чем мы сможем переключить использование строки команды.
Я написал простой скрипт для автоматического перемещения всех входов приемника.
Использование: ./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
Улучшенная версия @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
Существует скрипт ruby (который я изначально разветвлял и переписывал) , который позволяет вам изменять приемники по умолчанию, громкость и состояние отключения звука из командной строки.
Я собрал воедино материал из нескольких разных мест и придумал этот скрипт, чтобы настроить 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
КРУЖЕВНЫЕ МОЙКИ.
Скрипт 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
На основе ответа 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
Я думаю, что существует еще одна опция, которую стоит упомянуть, и это доступно на уровне официальной страницы для 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
Я настроил @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
И вот сценарий, который переключится между приемниками также:
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