ตั้งค่าเอาต์พุตเสียง HDMI โดยอัตโนมัติเมื่อเชื่อมต่อ / ตัดการเชื่อมต่อ


20

ฉันมีการตั้งค่าหน้าจอคู่บนแล็ปท็อปของฉัน (ใช้ 12.04 LTS) โดยใช้จอแสดงผลที่เชื่อมต่อด้วย HDMI ทุกอย่างทำงานได้ดี แต่ทุกครั้งที่ฉันเชื่อมต่อ / ถอดสายเคเบิลฉันต้องไปที่การตั้งค่าเสียงและเปลี่ยนอุปกรณ์เสียงออกด้วยตนเอง

มีวิธีใดบ้างที่จะเปลี่ยนอุปกรณ์เสียงออกในการเชื่อมต่อ / ตัดการเชื่อมต่อของสายเคเบิลดังนั้นเมื่อฉันเชื่อมต่อจอแสดงผลของฉันเสียงที่ถูกตั้งค่าเป็น HDMI และเมื่อฉันตัดการเชื่อมต่อมันเสียงจะกลับไปที่ลำโพงแล็ปท็อป


ปัญหาเดียวกันที่นี่
ThiagoPonte

นี่เป็นครั้งแรกที่ฉันมาที่นี่เพื่อขอความช่วยเหลือในเรื่องนี้ ... ฉันอยู่ในเรือลำเดียวกันเวลา 12.10 น. มันน่ารำคาญ. เป็นเช่นนี้มาตั้งแต่ 10.10 ในประสบการณ์ของฉัน ต้องมีการกำหนดค่าที่สามารถจัดการกับสิ่งนี้ได้ แก้ไข: voices.canonical.com/david.henningsson/2012/04/14/…มันได้รับการกำหนดไว้อย่างมีวัตถุประสงค์ มันช่างน่ากลัว
user138216

ตรวจสอบว่าคำตอบของฉันทำงานร่วมกับคุณ
เซเลม

คำตอบ:


11

เพื่อประโยชน์ของผู้คนที่สะดุดกับคำถามนี้ - โซลูชันของ Salem ทำงานได้ดีสำหรับฉันใน 13.04 ฉันสิ้นสุดการรวบรวมบิตและชิ้นส่วนจากทั่วเว็บฉันคิดว่าตัวจัดการข้อตกลงสำหรับฉันคือการขาดตัวแปรสภาพแวดล้อม PULSE_SERVER

นี่คือคำตอบแบบเต็มของฉันซึ่งโดยทั่วไปแล้วการทำซ้ำโซลูชันของเซเลมกับชิ้นส่วนที่ขาดหายไปบางส่วน ฉันยังเปลี่ยนเป็นเชลล์สคริปต์ (แม้ฉันจะชอบ Python) เพราะฉันกลัวในตอนแรกว่าสคริปต์ Python ของฉันกำลังทำงานในปัญหาการนำเข้าพา ธ :


(เช่นเดียวกับคำตอบของ Salem) สร้างไฟล์/etc/udev/rules.d/hdmi_sound.rulesตามรูทด้วยเนื้อหา:

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

สร้างไฟล์/usr/local/bin/hdmi_sound_toggleเป็นรูทด้วยเนื้อหา:

#!/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 ฉันคิดว่า pactl กำลังมองหาตัวแปร env

อย่าลืมโหลดกฎ udev ของคุณ: sudo udevadm control --reload-rules

อัปเดตสคริปต์นี้ได้รับการอัพเดตสำหรับ 14.04 ก่อนหน้านั้นคุณจะใช้ USER_NAME แทน USER_ID ทุกที่


1
โปรดทราบว่าฉันต้องการผนวก| uniqคำสั่ง USER_NAME นอกจากนี้โปรดทราบว่าการตั้งค่าเสียงใน Ubuntu อาจเป็นการหลอกลวง ฉันไม่เห็นการเปลี่ยนแปลงในแผงการตั้งค่าเสียง แต่เมื่อฉันเล่นบางสิ่งเสียงจะสลับไปมาอย่างราบรื่นฉันยังสังเกตเห็นว่าหลังจากเสียบปลั๊กและถอดปลั๊ก HDMI ไม่กี่ครั้งสคริปต์ก็หยุดทำงาน เรียงลำดับของข้อบกพร่องใน udev)
FuegoFro

1
ฉันเพิ่ม| sort -uไปยังชื่อผู้ใช้เพราะมันบอกว่าตัวเลือกเพิ่มเติม elemer elemer --- ชื่อผู้ใช้ของฉัน เช่นเดียวกับโซลูชันของ FuegoFro ในตอนท้ายของวัน
elemer82

ฉันเคยใช้| grep -v ptsเพราะฉันมีผู้ใช้ "รูท" ที่นั่นด้วยเช่นกันเพราะฉันกำลังแก้ไขสคริปต์ผ่านเคทซึ่งเปิดรูทเทอร์มินัล
Auspex

รับ "การเชื่อมต่อล้มเหลว: การเชื่อมต่อถูกปฏิเสธ pa_context_connect () ล้มเหลว: การเชื่อมต่อถูกปฏิเสธ" เมื่อเรียกใช้ pactl : \
Tomislav Nakic-Alfirevic

7

ในที่สุดฉันก็สามารถทำให้งานนี้ใช้งานudevได้ ดังนั้นหากมีคนต้องการพฤติกรรมเดียวกันนี่คือขั้นตอน:

ก่อนอื่นเราต้องสร้างไฟล์ที่/etc/udev/rules.d/hdmi_sound.rulesมีเนื้อหาดังต่อไปนี้:

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

สิ่งนี้จะทำให้udevรันสคริปต์hdmi_sound_toggleทุกครั้งที่มีการเปลี่ยนแปลงการเชื่อมต่อ HDMI สคริปต์นั้นต้องมีสิทธิ์ดำเนินการและเนื้อหามีดังนี้:

#!/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))

อาจเป็นไปได้ว่าสามารถทุบตีได้ง่าย แต่เนื่องจากภาษาหลักของฉันคืองูใหญ่ฉันจึงใช้มัน ทุกอย่างทำงานได้ยกเว้นการแจ้งเตือน: มันไม่ปรากฏขึ้นฉันไม่รู้จริงๆว่าทำไม หากมีคนรู้วิธีการแก้ไขโปรดพูดอะไรบางอย่าง

หมายเหตุ: ชื่อของสคริปต์ / กฎ udev สามารถเปลี่ยนแปลงได้ แต่คุณต้องใช้เส้นทางแบบเต็ม


3

ขึ้นอยู่กับซาเลม 'คำตอบและdanielคำตอบ' s

ฉันใช้คำตอบของซาเลมและคำตอบของแดเนียลและทำการเปลี่ยนแปลงที่จำเป็นวิธีแก้ปัญหาของพวกเขาไม่ได้ผลสำหรับฉัน:

(คล้ายกับคำตอบของ Salem)

สร้างไฟล์/etc/udev/rules.d/hdmi_sound.rulesเป็นรูทด้วยเนื้อหา:

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

หมายเหตุ ACTION=="change", หายไป!

สร้างไฟล์/usr/local/bin/hdmi_sound_toggleเป็นรูทด้วยเนื้อหา:

#!/bin/sh
USER_NAME=`who | grep "(:0)" | cut -f 1 -d ' '| sort -u`
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

หมายเหตุ USER_NAME =who | grep "(:0)" | cut -f 1 -d ' '| sort -u ฉันเพิ่ม| sort -uเพราะไม่เช่นนั้นมันจะกลับมาพร้อมกับ -elemer elemer elemerชื่อผู้ใช้ของฉัน 3 ครั้ง

จากนั้นทำให้สามารถเรียกใช้งานได้ด้วย chmod 0755 /usr/local/bin/hdmi_sound_toggle

อย่าลืมโหลดกฎ udev ของคุณ: sudo udevadm control --reload-rules

สิ่งสำคัญสคริปต์นี้มีการปรับปรุงสำหรับ 14.04 ก่อนหน้านั้นคุณจะใช้ USER_NAME แทน USER_ID ทุกที่

เครดิต: ซาเลมและแดเนีย


1

Ubuntu 16.04 - 17.04 คำตอบ

ใช้งานได้กับ Ubuntu 16.04 - 17.04 ซึ่งมีข้อบกพร่องพร้อม Pulse Audio 8 สร้างไฟล์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สคริปต์


ขอบคุณมาก! มันทำงานบน Ubuntu 17.04 เช่นกัน! นี้ได้รับการ bugging ฉันสำหรับในขณะที่ยาวและนั่นก็คือวิธีง่ายๆ :)
Georgi Koemdzhiev

1
คุณเป็นที่ต้อนรับอย่างยิ่ง. ขอบคุณสำหรับความคิดเห็นยืนยันว่ามันเป็นสิ่งจำเป็นสำหรับ 17.04 เช่นกัน
WinEunuuchs2Unix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.