저는 자체 스피커가 있는 노트북을 가지고 있습니다. 그런 다음 연결했을 때 선호하는 더 나은 스피커를 갖춘 모니터(USB-C를 통한 DP, 스테레오 2.0)가 있습니다. 요리하는 동안 동영상을 보거나 들을 때 사용하는 휴대용 스피커(블루투스, 3.5 잭 및 마이크로 USB 연결, 스테레오)도 있습니다. 때로는 HDMI-AVR(5.1)을 통해 노트북을 홈 시어터에 연결하기도 합니다. 이들 모두는 동적으로 변경되며, 3개 또는 4개가 동시에 연결될 수 있습니다.
다음과 같이 장치의 우선순위를 설정하고 싶습니다.
- 조절기
- 휴대용 앰프
- 감시 장치
- 랩탑
이렇게 하면 구성을 변경할 때 마법처럼 자동으로 선택됩니다(하루에 여러 번 발생할 수 있음).
이제 PulseAudio는 가장 좋은 것을 선택하려고 시도하며 때로는 성공하고 때로는 그렇지 않습니다.
내 인터넷 검색이 정확하다면 구성 파일이나 일부 GUI를 통해 기본값을 설정할 수 없으므로 스크립트를 작성해야 합니다. 나는 이것에 조금 놀랐습니다. 나는 이것이 일반적인 사용 사례임에 틀림없다고 생각했습니다. 그래서 나는 그러한 스크립트를 작성하기 전에 내 연구가 잘못된 것인지 묻고 싶었습니다(또는 누군가 그러한 스크립트를 가지고 있다면 자유롭게 공유하십시오. 내가 찾은 유일한 것은 다음과 같습니다).https://askubuntu.com/questions/263248/set-hdmi-sound-output-automatically-on-connect-disconnect- 내 설정만큼 복잡하지는 않습니다)
저를 혼란스럽게 하는 또 다른 점은 "DELL U4320Q", "JieLi AC46" 등과 같은 장치의 실제 이름이 Gnome, KDE 또는 pactl(pactl 속성의 카드>device.product) .name의 모든 도구에 숨겨져 있다는 것입니다. UI에는 노출되지 않습니다. 왜 그런 겁니까? 확실히 사람이 더 쉽게 읽을 수 있을 것입니다. 모니터의 경우 일반적으로 "dmi-output-0: HDMI/DisplayPort"와 같은 메시지가 표시됩니다. 모니터를 어느 포트에 연결했는지(어떤 포트가 0이고 어떤 포트가 1인지) 어떻게 알 수 있습니까? 이에 대한 이유가 있습니까? 설치를 업데이트할 때마다 개선 사항이 있는지 궁금하지만 기본적으로 동일하게 유지됩니다. Pipewire가 이 문제를 해결하는 데 도움이 될까요? 저는 PulseAudio가 이러한 사용법을 쉽게 만들어줄 것이라고 생각합니다 :-).
답변1
/usr/local/bin/hdmi_sound_toggle.py
그래서 자동으로 전환되도록 다음 스크립트를 작성했습니다 . 여기에 제공된 스크립트를 사용합니다.https://stackoverflow.com/a/24933353/1269040어떤 모니터가 연결되어 있는지 알아보세요.
#!/usr/bin/env python3
import subprocess
# find_monitors is the script from the internet to check EDID data - I put it into $PATH
# the following implements "find_monitors 2>/dev/null | grep '#' 2>/dev/null 1"
# my internal monitor is confusing the script, outputing some weird binary data, so I strip it on the second line
monitors_gibberish = subprocess.check_output(("find_monitors"), shell=True, stderr=subprocess.DEVNULL)
monitors_one_line = monitors_gibberish.replace(b'# eDP-1-1 HDMI \xff\xff\xff\xff\xff\xff\r\xae\x0c\x15', b'').decode("UTF-8")
monitors_lines = [i for i in monitors_one_line.split('\n') if i]
default_sink = ''
alsa_card = "pci-0000_01_00.1"
port_number = 0
profile_name = ''
if "H/K AV AMP" in monitors_one_line:
# AVR is connected through HDMI port and that has always number three, so it has "-extra2" added the profile name
profile_name = "hdmi-surround-extra2"
elif "DELL U4320Q" in monitors_one_line:
for i in monitors_lines:
if "DELL U4320Q" in i:
# This is being split: '# DP-0 DisplayPort DELL U4320Q'
# DP numbering start at 0, HDMI numbering in Pipewire/alsa starts at 1
port_number = int(i.split(" ")[1].split("-")[1]) + 1
if port_number == 1:
profile_name = "hdmi-stereo"
elif port_number == 2:
profile_name = "hdmi-stereo-extra1"
# first we need to set default profile for HDMI - it tells Pipewire to which device it should send audio streams over HDMI
if profile_name:
default_sink = 'alsa_output.' + alsa_card + "." + profile_name
subprocess.run(["pactl", "set-card-profile", "alsa_card." + alsa_card, "output:" + profile_name])
# and now we switch the default sink, ie. device that should play all audio by default
subprocess.run(["pactl", "set-default-sink", default_sink])
~
자동으로 실행하려면 다음과 같이 작성합니다.
SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/run_hdmi_sound_toggle"
그냥 도망 /etc/udev/rules.d/99-hdmi_sound.rules
쳤어요 sudo udevadm control --reload-rules
. /usr/local/bin/run_hdmi_sound_toggle
다음은 루트에서 실행되고 사용자로 실행되는 Pipewire/PulseAudio에 연결할 수 없는 udev를 처리하는 래퍼 스크립트입니다.
#!/bin/bash
systemctl [email protected] --user --now start hdmi_sound_toggle.service
해당 시스템 서비스 파일 ~/.config/systemd/user/hdmi_sound_toggle.service
은 다음과 같습니다.
[Unit]
Description=Runs /usr/local/bin/hdmi_sound_toggle.py to switch to the correct sound output
[Service]
Type=oneshot
ExecStart=/usr/local/bin/hdmi_sound_toggle.py
그런 다음 DHMI/USB-C/DP 플러그/분리에서 작동합니다.
DP 또는 HDMI를 통해 연결된 장치에서만 작동합니다. Pipewire는 USB/블루투스 장치를 잘 처리하는 것 같습니다.