web-dev-qa-db-ja.com

HDMIをラップトップに接続したときにHDMIオーディオに切り替える(14.04)

私はラップトップがプラグインされたときにオーディオをHDMIに切り替え、取り外されたときに標準のアナログに戻すようにしようとしています。

切り替えを実行するスクリプトをトリガーするudevルールを設定しましたが、動作させるのに問題があります:

  • サウンド設定でHDMIオーディオ出力を選択するまで、利用可能なシンクとして認識されず、HDMIオーディオ出力が選択されると、アナログ出力は表示されなくなります。

以下を参照してください。

# HDMI plugged in, not selected in Sound settings.
$ pactl list short sinks 
5   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   SUSPENDED
kingamajick@kingamajick-laptop: ~

# HDMI selected in sound settings    
$ pactl list short sinks 
7   alsa_output.pci-0000_00_1b.0.hdmi-stereo    module-alsa-card.c  s16le 2ch 48000Hz   SUSPENDED
kingamajick@kingamajick-laptop: ~

# HDMI removed
$ pactl list short sinks 
9   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 48000Hz   SUSPENDED

出力を切り替えるトグルを使用しているスクリプトは次のとおりです。

#!/bin/bash
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))

if [ $HDMI_STATUS = "connected" ]
then
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done-server $Pulse_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo
fi

スクリプトは、サウンド設定でHDMIを選択する前にトリガーすると、そのようなシンクがないというエラーを出します。

12
Kingamajick
  1. 利用可能なカードとプロファイルを確認する

    pactl list cards
    
  2. デフォルトのシンクと移動ストリームを設定する前に、次のコマンドをスクリプトに追加してプロファイルを変更します

    pactl [options] set-card-profile  CARD PROFILE
    

(したがって、サウンド設定から手動で切り替える必要はありません)

参照:

pactl -hman pactl

9
user.dz

これに基づいて link およびこれに link ... iテストし、WORKS FINE ubuntu 14.04

/etc/udev/rules.d/100-hdmi_sound.rulesにルールを作成する必要があります

このコンテンツ

SUBSYSTEM=="drm", ACTION=="change", RUN+="/lib/udev/hdmi_sound_toggle.sh"

次に作成する

Sudo -H gedit /lib/udev/hdmi_sound_toggle.sh

あなたのコンテンツ

#!/bin/bash

HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))
if [ $HDMI_STATUS = "connected" ]
then
    pactl set-card-profile 0 output:hdmi-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-card-profile 0 output:analog-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done
fi

私はスペイン語を話した私の英語を申し訳ありません。

8
Sk.

これに少し苦労しました。元のスクリプトをコピーし、提案されたとおりに変更しましたが、現在は動作します。

他の人が使いやすくするためにここに含めています。

#!/bin/bash
## From: https://askubuntu.com/questions/458194/switching-to-hdmi-audio-when-hdmi-is-plugged-into-a-laptop-14-04
## Script needs to be triggered by a udev rule
## Works manually now

##source ${HOME}/bin/bash_trace
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))

if [ $HDMI_STATUS = "connected" ]
then
    pactl set-card-profile 0 output:hdmi-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-card-profile 0 output:analog-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done
fi

今、私はちょうどudevでそれをトリガーしたいのですが、どうすればいいのかわかりません。

4
Joe

提供されたスクリプトは、Ubuntu 14.04ですぐにudevで機能しませんでした。追加する必要がありました。

export DISPLAY=:0

最初に、2つのpacmdコマンドをpactlに変換し、最後にudevルールからSudo -s -u(ユーザー)を使用してスクリプトを実行します。

#!/bin/bash
## From: https://askubuntu.com/questions/458194/switching-to-hdmi-audio-when-hdmi-is-plugged-into-a-laptop-14-04
## Script needs to be triggered by a udev rule
## Works manually now

export DISPLAY=:0

##source ${HOME}/bin/bash_trace
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pactl list sink-inputs | grep Input | awk '{print $3}' | sed -r 's/^.{1}//')

if [ $HDMI_STATUS = "connected" ]
then
    pactl set-card-profile 0 output:hdmi-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pactl move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-card-profile 0 output:analog-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pactl move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done
fi
3
Ken

さて、提供されたすべてのスクリプトは私にとってはうまくいきませんでしたが(Ubuntu 16.04)、 見つけました ワンクリックでサウンド出力を変更できるこのアプリインジケーター:

https://github.com/lkettenb/sound-output-switcher

(注:最初にappindicatorパッケージをインストールする必要があります:Sudo apt-get install python-appindicator

代替ソリューションであるにもかかわらず、私と同じ状況にある可能性のある他の人のためにこれをここに残すと思いました...しかし、それは非常に簡単になり、個別です;-)

2
Nat Azodnem

再度、以前に基づいた別のソリューション(16.04でテスト済み)が、適切なサーバーを指す適切なpactlを使用して機能するいくつかの改善を加えて(カードおよびプロファイルの名前を自動的に取得するように改善できます。pactl listまたはpactl info今のところ)。

#!/bin/bash

USER_NAME=$(who | grep tty$(Sudo fgconsole) | cut -f1 -d' ')
USER_ID=$(id -u "$USER_NAME")
HDMI_STATUS=$(</sys/class/drm/card0/*HDMI*/status)

HDMI_CARD="pci-0000_00_03.0"
HDMI_PROFILE="hdmi-stereo-extra1"

INTERNAL_CARD="pci-0000_00_1b.0"
INTERNAL_PROFILE="analog-stereo"

export LANG=C
export Pulse_SERVER="unix:/run/user/$USER_ID/Pulse/native"

function pactl_cmd() {
  Sudo -u $USER_NAME pactl --server $Pulse_SERVER $*
}

if [ "$HDMI_STATUS" = "connected" ]; then
  CARD=$HDMI_CARD
  OUTPUT=$HDMI_PROFILE
else
  CARD=$INTERNAL_CARD
  OUTPUT=$INTERNAL_PROFILE
fi

pactl_cmd set-default-sink alsa_output.$CARD.$OUTPUT
pactl_cmd set-card-profile alsa_card.$CARD output:$OUTPUT

INPUTS=($(pactl_cmd list sink-inputs | grep "^Sink Input #"|cut -d# -f2))
for i in ${INPUTS[*]}; do
  pactl_cmd move-sink-input $i alsa_output.$CARD.$OUTPUT
done

関連 要点はこちら

0
Treviño

Udevスクリプトはルートとして実行されますが、使用しているディスプレイマネージャーを知る必要もあります。このスクリプトは動作するはずですが、そのためにはディスプレイマネージャを認証する必要があります。

使用しているDMを見つけます:

pgrep -a Xorg

-authオプションを参照してください。ディスプレイマネージャーが表示されます。最新のUbuntuリリースでは、sddmまたはlightdmである可能性があります。

この行は、次のようにXAUTHORITY変数としてエクスポートする必要があります。

ls /car/run/sddm*

たとえば、これは有効な出力である可能性があります。

/var/lib/mdm/:0.Xauth(これはスクリプトで使用されます)

これは、スクリプトが次のように見える必要がある方法です。

#!/bin/bash
export DISPLAY=:0
export XAUTHORITY=`ls /var/run/sddm*`
HDMI_STATUS="$(cat /sys/class/drm/card0-HDMI-A-1/status)"
USER=`whoami`
export XAUTHORITY=/home/$USER/.Xauthority
export DISPLAY=:0

if [ "$HDMI_STATUS" = connected ];
then
    Sudo -u $USER pactl set-card-profile 0 output:hdmi-stereo+input:analog-stereo
else
    Sudo -u $USER pactl set-card-profile 0 output:analog-stereo+input:analog-stereo
fi
exit 0

これにより、ディスプレイマネージャーがHDMI出力を変更できるようになります。手順に従って、udevルールファイルを作成し、スクリプトを実行可能にします。

0
LinuxHelper