按属性查找pulseaudio sink-input索引

时间:2016-09-28 01:19:20

标签: pulseaudio

pactl list sink-inputspacmd list-sink-inputs的输出都包含“属性”部分:

Properties:
    media.name = "ALSA Playback"
    application.name = "ALSA plug-in [snapclient]"
    native-protocol.peer = "UNIX socket client"
    native-protocol.version = "29"
    application.process.id = "6393"
    application.process.user = "root"
    application.process.host = "xxxxxx"
    application.process.binary = "snapclient"
    application.language = "C"
    application.process.machine_id = "8dadf95c2f504864bc0f8b3ab149cbe0"
    application.process.session_id = "c4"
    module-stream-restore.id = "sink-input-by-application-name:ALSA plug-in [snapclient]"

我想知道是否有办法通过application.process.idapplication.process.binary直接查找接收器输入的索引,而不需要解析上述命令的多行输出或者写一个单独的C程序。

3 个答案:

答案 0 :(得分:1)

某些命令也接受唯一名称而不是id,但是您尝试使用的名称似乎无法执行此操作。可能是因为名称不是唯一的,并且可能存在多个匹配项。你需要自己解析它。这就是我想出的:

pacmd list-sink-inputs |
tr '\n' '\r' |
perl -pe 's/ *index: ([0-9]+).+?application\.name = "([^\r]+)"\r.+?(?=index:|$)/\2:\1\r/g' |
tr '\r' '\n'

perl -pe就像sed一样,更好。这基本上匹配index: [id] [anything] application.name = [name] [anything]并将输出格式化为类似

3 sink input(s) available.
"speech-dispatcher":166
"SoX":407
"Clementine":413

然后你可以grep或sed。

答案 1 :(得分:0)

虽然它确实解析了输出并且还没有为你可能正在寻找的id做任何匹配,但是这个方法将提供一种方法,通过一些修改,通过sink id获取该信息:

pactl list sink-inputs | while read -r line ; do

  #echo "Processing ${line}"
  echo $line | grep -oP 'Sink Input #\K[^$]'
  echo $line | grep -oP 'application.process.id = "\K[^"]+'
  echo $line | grep -oP 'application.process.binary = "\K[^"]+'

done

答案 2 :(得分:0)

很长、易于理解、可维护的方法(使用application.process.binary

结果

ffmpeg | 3
firefox-esr | 24
firefox-esr | 58
vlc | 43

Bash 脚本

str="$(pacmd list-sink-inputs)"

list1=$(printf '%s' "$str" | grep 'index: ')
list2=$(printf '%s' "$str" | grep 'application.process.binary = "')

arr1=()
arr2=()

while read line; do
    arr1+=("${line:7}")
done <<< "$list1"

while read line; do
    arr2+=("${line:30:-1}")
done <<< "$list2"

for index in ${!arr1[@]}; do
    s1="${arr1[index]}"
    s2="${arr2[index]}"

    echo "$s2 | $s1"
done

另一种方法(有点晦涩)

str="$(pacmd list-sink-inputs)"

arr1=($(printf '%s' "$str" | grep 'index: ' | rev | cut -d' ' -f 1 | rev))
arr2=($(printf '%s' "$str" | grep 'application.process.binary' | cut -d'"' -f 2))

for index in ${!arr1[@]}; do
    s1="${arr1[index]}"
    s2="${arr2[index]}"

    echo "$s2 | $s1"
done

最后,我找到了最短的解决方案:

str="$(pacmd list-sink-inputs)"

paste -d\| \
<(printf '%s' "$str" | grep 'application.process.binary' | cut -d'"' -f 2) \
<(printf '%s' "$str" | grep 'index: ' | rev | cut -d' ' -f 1 | rev)