스크립트를 작성하지 않고도 동적으로 변경되는 기본 스피커 순서를 설정할 수 있습니까?

스크립트를 작성하지 않고도 동적으로 변경되는 기본 스피커 순서를 설정할 수 있습니까?

저는 자체 스피커가 있는 노트북을 가지고 있습니다. 그런 다음 연결했을 때 선호하는 더 나은 스피커를 갖춘 모니터(USB-C를 통한 DP, 스테레오 2.0)가 있습니다. 요리하는 동안 동영상을 보거나 들을 때 사용하는 휴대용 스피커(블루투스, 3.5 잭 및 마이크로 USB 연결, 스테레오)도 있습니다. 때로는 HDMI-AVR(5.1)을 통해 노트북을 홈 시어터에 연결하기도 합니다. 이들 모두는 동적으로 변경되며, 3개 또는 4개가 동시에 연결될 수 있습니다.

다음과 같이 장치의 우선순위를 설정하고 싶습니다.

  1. 조절기
  2. 휴대용 앰프
  3. 감시 장치
  4. 랩탑

이렇게 하면 구성을 변경할 때 마법처럼 자동으로 선택됩니다(하루에 여러 번 발생할 수 있음).

이제 PulseAudio는 가장 좋은 것을 선택하려고 시도하며 때로는 성공하고 때로는 그렇지 않습니다.

  1. 내 인터넷 검색이 정확하다면 구성 파일이나 일부 GUI를 통해 기본값을 설정할 수 없으므로 스크립트를 작성해야 합니다. 나는 이것에 조금 놀랐습니다. 나는 이것이 일반적인 사용 사례임에 틀림없다고 생각했습니다. 그래서 나는 그러한 스크립트를 작성하기 전에 내 연구가 잘못된 것인지 묻고 싶었습니다(또는 누군가 그러한 스크립트를 가지고 있다면 자유롭게 공유하십시오. 내가 찾은 유일한 것은 다음과 같습니다).https://askubuntu.com/questions/263248/set-hdmi-sound-output-automatically-on-connect-disconnect- 내 설정만큼 복잡하지는 않습니다)

  2. 저를 혼란스럽게 하는 또 다른 점은 "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/블루투스 장치를 잘 처리하는 것 같습니다.

관련 정보