web-dev-qa-db-ja.com

内蔵スピーカーとHDMIスピーカーを自動的に切り替える

ヘッドフォンをラップトップのAuxジャックに接続すると、内蔵スピーカーが自動的にミュートされ、ヘッドフォンから音が出ます。私はまさにHDMIにそれが欲しいです。

ビデオを見るために、内蔵スピーカー付きのモニターをラップトップに接続します。ビデオがモニター(デスクから3 m離れた場所)にあるときは非常に奇妙ですが、ラップトップの内部スピーカーから音が出ます(ラップトップはデスクに座っています)。

もちろん、サウンド設定に移動して、出力チャンネルをHDMIに切り替えることができます。しかし、その後、数時間前にHDMIケーブルを取り外し、まったく別の場所にある場合でも、サウンドサーバーはまだHDMI経由で再生しようとしていますが、何も接続されていないため、サウンドは再生されません。

HDMIを介してデバイスが接続されていないときに自動的に内部スピーカーに戻ることはより重要ですが、デバイスが接続されているときにHDMIを介してサウンド出力に切り替えることは非常に便利です。

これは明らかに11.10で機能しました ですが、16.04では機能しません。

17
UTF-8

バックグラウンド

サスペンド/レジューム中に、音声がHDMI TVからラップトップスピーカーに切り替わるときに、同様の問題が発生しました。再開時にサウンドはラップトップスピーカーにとどまり、System Settings-> Soundで出力デバイスをテレビに手動でリセットする必要があります。

これはbuntu 14.04から16.04へのアップグレードに関する最初の迷惑な経験の1つであり、ルートは16.04 LTSが付属するPulseAudio 8へのアップグレードでした

よく検索した後、TV-soundというスクリプトを作成しました。私はあなた自身のようにテレビを抜き差しすることはしませんが、私はいくつかのグーグル検索を行い、あなたの状況で動作するスクリプトのバリエーションを作成しました。私はそれをテストしましたが、動作します。

手順1:接続されたデバイス間で音声を切り替えるスクリプトを作成する

Udevが呼び出すhotplugtvというスクリプトを作成します。ただし、この同じスクリプトは多くの場所で呼び出すことができます。たとえば、テスト中にlock-screen-timerで使用し、画面ロック中に音がラップトップに戻りました。

cd /usr/local/bin
Sudo touch hotplugtv
Sudo chmod +x hotplugtv
gksu gedit hotplugtv

空白の画面でエディターが開いたら、以下をコピーして貼り付けます。

#! /bin/bash

# NAME: hotplugtv
# PATH: /usr/local/bin
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: called from /etc/udev/rules.d/99-monitor-hotplug.rules
# 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.

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

exit 0

rickの2つのオカレンスを独自のユーザーID、つまりUTF-8などに置き換える必要があります。

ユーザー名が自動的にbash変数に設定されると、これはよりプロフェッショナルになる可能性がありますが、私はまだそれほど熟練していません:(とにかく、ファイルを保存してgeditを終了します.

ステップ2:udevルールを作成する

udevは、HDMIモニターを接続したり取り外したりすると、ホットプラグイベントを監視します。次を入力して、新しいルールを作成します。

cd /etc/udev/rules.d
Sudo cp 70-persistent-net.rules 99-hotplugtv.rules
gksu gedit 99-hotplugtv.rules

注:ファイル70-persistent-net.rulesがディレクトリに存在しない場合、そこに他のファイルをコピーします。ファイルの内容は必要ありません。ファイルのパーミッションが同じであることを確認するためのファイルのパーミッションのみが必要です。

エディターは無関係なテキストを表示し、強調表示して削除します。次に、以下のコードを強調表示して、エディターに貼り付けます。

# NAME: 99-hotplugtv.rules
# PATH: /etc/udev/rules.d
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: automatically called on system events
# DATE: Created Nov 26, 2016.
# NOTE: in future may requre systemd service hooks

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

ファイルを保存して終了します。

(再起動せずに)ルールを有効にするには、udevをリロードする必要があります。

Sudo udevadm control --reload-rules

これで、HDMIモニター/テレビのプラグを抜き差しでき、サウンドが適切に切り替わります。

警告

私のシステムでは、HDMIが接続されていない場合、サウンドは自動的にラップトップスピーカーに戻ります。お使いのシステムではそうではありませんでした。 HDMIが接続されていないときにラップトップスピーカーに音が出ない場合は、コードをさらに強化する必要があります。物事がどのように機能するか、またはうまくいかないかを以下のコメントで返信してください。

CLIでのクイックテスト

次を使用して、ターミナルでコードをすばやくテストできます。

    export Pulse_RUNTIME_PATH="/run/user/1000/Pulse/";
  • HDMI/TVへの切り替え:

        Sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
    
  • 内蔵スピーカーに切り替えます:

        Sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
    
  • rickをユーザー名に置き換えてください。

  • 最初のexport行はおそらく必要ありませんが、念のために含めました。
  • 複数のサウンドカードがある場合、またはhdmi-stereo以外の調整が必要な場合は、スクリプトを記述する前に正しいパラメーターを見つける必要があることは明らかです。

PulseAudio内でデバイス名を解読する

以下のコードは、同じコマンドを2回使用しています。サウンドが外部HDMI TVに設定されると1回。サウンドがラップトップの内蔵スピーカーに設定される2回目。 PulseAudioが使用する名前が表示されるたびに:

$ pacmd list-sinks | grep -e 'name:' -e 'index'
  * index: 28
    name: <alsa_output.pci-0000_00_1b.0.hdmi-stereo>
───────────────────────────────────────────────────────────────────────────────
$ pacmd list-sinks | grep -e 'name:' -e 'index'
  * index: 30
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>

複数のサウンドカードがある場合

コマンドaplay -lを使用して、番号0より大きいカードがあるかどうかを確認します。その場合、スクリプトで適切なカード番号を使用する必要があります。例えば:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: 92HD91BXX Analog [92HD91BXX Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

上記の例では、出力ソースが異なるすべてのカード番号は0です。 USBスピーカーを使用している場合は、0以外のカード番号を使用できます。

2016年12月2日編集

何らかの不明な理由により、スクリプトは今日壊れました。上記のコードは「$(cat/sys/class/drm/card0-HDMI-A-1/status」を読み取りましたが、card0card1に変更する必要があり、上記のコードは修正されました2016年11月26日以降、Ubuntuの定期的な更新以外にシステムの変更点を説明することはできません。

2016年12月14日編集

上記のコードは再び「$(cat/sys/class/drm/card0-HDMI-A-1/status」に切り替える必要がありました。card0card1の間のコードを修正する代わりにブートし、プログラムを修正してcard*を参照して両方のシナリオをキャプチャします。

7