使用 wpctl 为每个应用设置自己的音量

使用 wpctl 为每个应用设置自己的音量

RayAlto OP

我从 2023.02 开始转到 Wayland ,然后就跟着 Arch Wiki 用 Pipewire 了,基本上没有任何额外配置, Arch 怎么打包我怎么用。

某次 pacman -Syu 之后 mpv 音量突然变得很低,我以为 mpv/Pipewire 就是这样设计的,但把 mpv 的音量拉到 100 以上音频会失真,所以我把全局音量(不知道叫什么好,这里想表示的是与音频输出设备绑定的音量, Pipewire 称之为 global volume )调大了,就这样将就用了好久,但今天偶然一次用 vlc 播放音频,声音大的吓我一跳我释放忍术

Pipewire 环境下 mpv 的音量控制

经过一番探索,目前 Pipewire 环境下使用 mpv 播放音频时音量由三个独立的值决定:

  1. Pipewire 的 global volume
  2. Pipewire 下 mpv 对应的 channel volume
  3. mpv 自己的音量。

我的情况就是 global volume 和 mpv 的音量都能看到所以是正常的,但因为我没有安装一个 GUI 工具来调整音量,所以我以为我没动过 channel volume ,而实际上不知道什么时候 channel volume 被调整过,导致整体音量不正常。

A.使用 mpv 更改 channel volume

可以通过 mpv 指令 set ao-volume 100 把 mpv 的 channel volume 调回 100 。需要注意的是前提是 mpv 的 --pipewire-volume-mode 选项的值为 channel (即默认值)。

比如默认情况下使用 mpv 播放媒体时按下 `(backtick) 可以呼出 mpv 的 console ,然后执行 set ao-volume 100 即可把 channel volume 拉满,比如像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ mpv --audio-display=no --shuffle ./
○ Image --vid=1 (mjpeg 596x596)
● Audio --aid=1 (flac 2ch 96000 Hz)
File tags:
Artist: Virtual Riot
Album: Sugar Rush Remix EP
Title: Sugar Rush (Barely Alive Remix)
AO: [pipewire] 96000Hz stereo 2ch s32
[cplayer] ○ Image --vid=1 (mjpeg 596x596)
[cplayer] ● Audio --aid=1 (flac 2ch 96000 Hz)
[display-tags] File tags:
[display-tags] Artist: Virtual Riot
[display-tags] Album: Sugar Rush Remix EP
[display-tags] Title: Sugar Rush (Barely Alive Remix)
[cplayer] AO: [pipewire] 96000Hz stereo 2ch s32
> set ao-volume 100
A: 00:00:21 / 00:04:13 (8%) Cache: 232s/100MB

B.使用 wpctl 更改 channel volume

我平时只用 wpctl 调整 global volume ,比如我的 Hyprland 配置是这样的:

1
2
3
bindel = , XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ && notify-send -u critical Volume 'current: '$(awk "{print $(wpctl get-volume @DEFAULT_AUDIO_SINK@ | cut -d' ' -f 2) * 100}" <<< '')
bindel = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- && notify-send -u critical Volume 'current: '$(awk "{print $(wpctl get-volume @DEFAULT_AUDIO_SINK@ | cut -d' ' -f 2) * 100}" <<< '')
bindel = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle && wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED && notify-send -u critical Volume 'muted' || notify-send -u critical Volume 'non-muted'

也没仔细研究过怎么给每个应用设置自己的音量(毕竟我也不是专业用户,我用到的应用都有自己的音量控制逻辑),其实 wpctl 可以设置每个应用的 channel volume ,而且与应用自己的音量逻辑是分离的(至少 mpv 默认是分离的,而 Firefox 是一体的),想要设置 channel volume 可以先看看对应的 ID 是多少:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ wpctl status
PipeWire 'pipewire-0' [1.2.5, rayalto@RayAltoXL, cookie:3589796466]
└─ ...

Audio
├─ ...

└─ Streams:
80. mpv
34. output_FL > ALC269VC Analog:playback_FL [active]
35. output_FR > ALC269VC Analog:playback_FR [active]

Video
└─ ...

Settings
└─ ...

Audio 下的 Streams 列表,我这里只有一个 mpv ,对应的 ID 为 80 ,可以看看 channel volume 是多少:

1
2
$ wpctl get-volume 80
Volume: 0.60

表示音量为 0.6 ,拉满:

1
$ wpctl set-volume 80 1

总结

其实还是我太菜了,之前 PulseAudio 明明也是差不多的逻辑,但 Pipewire 就没想到,被 pavucontrol 惯坏了。