接続/切断時にHDMIサウンド出力を自動的に設定する

接続/切断時にHDMIサウンド出力を自動的に設定する

HDMI 接続ディスプレイを使用して、ラップトップ (12.04 LTS を使用) にデュアル スクリーン セットアップをしています。すべて正常に動作しますが、ケーブルを接続/切断するたびに、サウンド設定に移動してサウンド出力デバイスを手動で変更する必要があります。

ケーブルの接続/切断時にサウンド出力デバイスを変更して、ディスプレイを接続するとサウンド出力が HDMI に設定され、切断するとサウンドがラップトップのスピーカーに戻るようにする方法はありますか?

答え1

この質問に遭遇した人のために - Salem の解決策は 13.04 でほぼ機能しましたが、最終的には Web のあちこちから断片的な情報を集めました。私にとって決定的な問題は、環境変数 PULSE_SERVER がなかったことです。

これが私の完全な解決策です。基本的には Salem の解決策を少しだけ省略して繰り返したものです。また、最初は Python スクリプトがインポート パスの問題に遭遇するのではないかと心配したため、シェル スクリプトとしてやり直しました (Python が大好きですが)。


/etc/udev/rules.d/hdmi_sound.rules(Salem の回答と同じ)次の内容のファイルを root として作成します。

SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"

/usr/local/bin/hdmi_sound_toggle次の内容のファイルを root として作成します。

#!/bin/sh
USER_NAME=`who | grep "(:0)" | cut -f 1 -d ' '`
USER_ID=`id -u $USER_NAME`
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`

export PULSE_SERVER="unix:/run/user/"$USER_ID"/pulse/native"

if [ $HDMI_STATUS = "connected" ]
then
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:hdmi-stereo+input:analog-stereo
else
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo
fi

次に、実行可能にしますchmod 0755 /usr/local/bin/hdmi_sound_toggle

このスクリプトはできる限り汎用的に作成しようとしましたが、HDMI_STATUS ファイルのパスや使用するプロファイルなど、いくつかの行を変更する必要があるかもしれません。実行してpactl list cards「プロファイル」の下を見ると、プロファイルの一覧が表示されます。

PULSE_SERVERを設定するときにキーワード「export」を削除するとスクリプトが失敗することに注意してください。pactlはenv変数を探していると思います。

udev ルールをリロードすることを忘れないでください:sudo udevadm control --reload-rules

アップデートこのスクリプトは14.04用に更新されています。それ以前は、どこでもUSER_IDの代わりにUSER_NAMEを使用していました。

答え2

Ubuntu 16.04 - 20.04 回答

これは、Pulse Audio 8 でバグが発生した Ubuntu 16.04 - 20.04 で動作します。ファイルを作成しhotplugtv(またはhotplug-hdmi必要に応じて)、次の行をコピーします。

#!/bin/bash

# NAME: hotplugtv
# PATH: /home/$USER/bin
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: called from /etc/udev/rules.d/99-hotplugtv.rules 
#       and /home/$USER/bin/lock-screen-timer
# DATE: Created Nov 26, 2016.
# NOTE: logs output using log-file
# UPDT: Dec 14, 2016 - Sometimes /sys/class/drm/card0 & sometimes /sys/class/drm/card1
#       so use /sys/class/dmcard* instead.
#       Dec 21, 2016 - Relocated to /home/$USER/bin for calling by lock-screen-timer
#       Aug 06, 2017 - Convert from home grown log-file to universal logger command.

if [[ $(cat /sys/class/drm/card*-HDMI-A-1/status | grep -Ec "^connected") -eq 1 ]]; then
        logger -t /home/rick/bin/log-hotplugtv "HDMI TV connected"
        /bin/sleep 2;
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
else
        logger -t /home/rick/bin/log-hotplugtv "HDMI TV disconnected"
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
fi

exit 0

重要:ユーザー名「rick」を自分のユーザー名に変更します。

ホットプラグ イベント中にこのスクリプトを呼び出すには、次の内容を含むudevファイルを作成します/etc/udev/rules.d/99-hotplugtv.rules

ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/home/rick/bin/hotplugtv"

/home/rick/bin/スクリプトを配置したパスに変更しますhotplugtv

答え3

最終的に、 を使用してこれを動作させることができましたudev。 同じ動作を希望する人がいる場合は、次の手順に従ってください。

/etc/udev/rules.d/hdmi_sound.rulesまず、次の内容のファイルを作成する必要があります。

    SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"

これにより、HDMI 接続が変更されるたびにudevスクリプトが実行されます。そのスクリプトには実行権限が必要であり、内容は次のとおりです。hdmi_sound_toggle

#!/usr/bin/env python

import subprocess
from syslog import syslog

def output(cmd):
    return subprocess.check_output(cmd, shell=True)

# the following variables may need some modification.
user = "my_username"
card = "/sys/class/drm/card0"
dev_speaker = "output:analog-stereo+input:analog-stereo"
dev_hdmi = "output:hdmi-stereo+input:analog-stereo"
#

interfaces = output("ls {0}".format(card), ).split("\n")

vga = filter(lambda x: "VGA" in x, interfaces)[0]
hdmi = filter(lambda x: "HDMI" in x, interfaces)[0]

syslog("HDMI connection was changed!")

hdmi_connected = output("cat {0}/{1}/status".format(card,hdmi)).startswith("connected")
title = "HDMI was {0}".format("connected" if hdmi_connected else "disconnected")
message = "Audio output has changed to {opt}.".format(opt = "HDMI" if hdmi_connected else "built-in speakers")

cmd = "sudo -u " + user + " /usr/bin/pactl set-card-profile 0 " + (dev_hdmi if hdmi_connected else dev_speaker)

syslog("HDMI was connected." if hdmi_connected else "HDMI was disconnected.")
try:
    a = output(cmd)
    output("sudo -u {0} notify-send \"{1}\" \"{2}\"".format(user, title, message))
    syslog("Audio output changed.")
except Exception as ex:
    syslog("Error changing output device: " + str(ex))

おそらくこれは bash で簡単に作成できますが、私の主な言語は python なので、それを使用しました。通知以外はすべて動作します。通知が表示されません。理由は本当にわかりません。修正方法をご存知の方がいらっしゃいましたら、教えてください。

注意: スクリプト/udev ルールの名前は変更できますが、完全なパスを使用する必要があります。

答え4

もっと簡単な方法があります:

/etc/pulse/default.pa次のように、で default-sink と default-source を定義します。デフォルトのオーディオデバイスの設定

grep default- /etc/pulse/default.pa
load-module module-default-device-restore
set-default-sink alsa_output.pci-0000_00_1f.3.analog-stereo
set-default-source alsa_input.pci-0000_00_1f.3.analog-stereo

再試行する前に、pulseaudio を再起動することを忘れないでください。

pulseaudio -k

関連情報