Tự động đặt đầu ra âm thanh HDMI khi kết nối / ngắt kết nối


20

Tôi có thiết lập màn hình kép trên máy tính xách tay của mình (sử dụng 12.04 LTS) bằng màn hình được kết nối HDMI. Mọi thứ đều hoạt động tốt, nhưng mỗi khi tôi kết nối / ngắt kết nối cáp, tôi phải chuyển đến tùy chọn Âm thanh và thay đổi thiết bị phát âm thanh theo cách thủ công.

Có cách nào để thay đổi thiết bị đầu ra âm thanh khi kết nối / ngắt kết nối cáp, vì vậy khi tôi kết nối màn hình, đầu ra âm thanh được đặt thành HDMI và khi tôi ngắt kết nối, âm thanh sẽ quay trở lại loa máy tính xách tay?


Cùng một vấn đề ở đây.
ThiagoPonte

Đây là lần đầu tiên tôi đến đây để được giúp đỡ về điều này ... Tôi ở trên cùng một chiếc thuyền vào ngày 12.10. Phiền thật đấy. Đó là cách này kể từ 10.10 theo kinh nghiệm của tôi. Phải có một cấu hình ở đâu đó có thể xử lý việc này. EDIT: voices.canonical.com/david.henningsson/2012/04/14/NH Đó là mục đích của nó. Điều đó thật kinh khủng.
dùng138216

Kiểm tra nếu câu trả lời của tôi làm việc với bạn.
Salem

Câu trả lời:


11

Vì lợi ích của những người vấp phải câu hỏi này - giải pháp của Salem gần như đã có hiệu quả với tôi vào ngày 13.04, tôi đã kết thúc việc thu thập các mẩu và mẩu từ khắp nơi trên web, tôi nghĩ rằng công cụ giải quyết cho tôi là thiếu biến môi trường PULSE_SERVER

Đây là giải pháp đầy đủ của tôi, về cơ bản là lặp lại giải pháp của Salem với một vài phần còn thiếu. Tôi cũng đã làm lại nó dưới dạng tập lệnh shell (mặc dù tôi yêu Python) vì ban đầu tôi sợ rằng tập lệnh Python của tôi đang gặp vấn đề về đường dẫn nhập:


(giống như câu trả lời của Salem) Tạo một tệp /etc/udev/rules.d/hdmi_sound.rulesvới quyền root với nội dung:

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

Tạo một tệp /usr/local/bin/hdmi_sound_togglevới quyền root với nội dung:

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

Sau đó làm cho nó thực thi được với chmod 0755 /usr/local/bin/hdmi_sound_toggle

Tôi đã cố gắng tạo tập lệnh này chung chung nhất có thể, nhưng bạn vẫn có thể cần thay đổi một số dòng, chẳng hạn như đường dẫn tệp HDMI_STATUS hoặc các cấu hình được sử dụng. Bạn có thể xem danh sách các hồ sơ bằng cách chạy pactl list cardsvà tìm trong Tiểu sử.

Lưu ý rằng tập lệnh thất bại đối với tôi khi tôi xóa từ khóa "export" khi đặt PULSE_SERVER, tôi nghĩ pactl đang tìm kiếm biến env

Đừng quên tải lại các quy tắc udev của bạn: sudo udevadm control --reload-rules

Cập nhật tập lệnh này được cập nhật cho 14.04. Trước đó, bạn sẽ sử dụng USER_NAME thay vì USER_ID ở mọi nơi


1
Lưu ý rằng tôi cần phải thêm | uniqvào lệnh USER_NAME. Cũng lưu ý rằng các cài đặt âm thanh trong Ubuntu có thể bị đánh lừa. Tôi không thấy các thay đổi trong bảng cài đặt âm thanh, nhưng một khi tôi đang chơi thứ gì đó, âm thanh sẽ chuyển đổi qua lại một cách trơn tru, tôi cũng nhận thấy rằng sau một vài lần cắm và rút HDMI, tập lệnh đã ngừng chạy (có thể một số loại lỗi trong udev).
FuegoFro

1
Tôi đã thêm vào | sort -utên người dùng bởi vì nó đang nói thêm tùy chọn elemer elemer --- Tên người dùng của tôi. Giống như giải pháp của FuegoFro vào cuối ngày.
elemer82

Tôi đã sử dụng | grep -v pts, vì tôi thực sự có một người dùng "root" ở đó, cũng vì tài khoản của tôi về việc tôi đang chỉnh sửa tập lệnh thông qua kate, có một thiết bị đầu cuối gốc mở.
Auspex 8/03/2015

Tiếp tục nhận "Lỗi kết nối: Kết nối bị từ chối pa_context_connect () không thành công: Kết nối bị từ chối" khi chạy pactl. : \
Tomislav Nakic-Alfirevic

7

Cuối cùng tôi đã quản lý để làm cho công việc này bằng cách sử dụng udev. Vì vậy, nếu ai đó muốn hành vi tương tự ở đây là các bước:

Đầu tiên chúng ta cần tạo một tệp /etc/udev/rules.d/hdmi_sound.rulescó nội dung sau:

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

điều này sẽ giúp udevthực thi tập lệnh hdmi_sound_togglemỗi khi có sự thay đổi trong kết nối HDMI. Kịch bản đó phải có quyền thực thi và nội dung như sau:

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

Có lẽ điều này có thể dễ dàng thực hiện trong bash, nhưng vì ngôn ngữ chính của tôi là python nên tôi đã sử dụng nó. Mọi thứ hoạt động ngoại trừ thông báo: nó không hiển thị, tôi thực sự không biết tại sao. Nếu ai đó biết cách sửa nó xin hãy nói điều gì đó.

Lưu ý: tên của quy tắc script / udev có thể được thay đổi, nhưng bạn cần sử dụng đường dẫn đầy đủ.


3

Dựa trên Salem 's câu trả lời và daniel câu trả lời' s

Tôi lấy câu trả lời của Salem và câu trả lời của daniel và thực hiện một số thay đổi cần thiết, giải pháp của họ không có tác dụng với tôi:

(tương tự như câu trả lời của Salem).

Tạo một tệp /etc/udev/rules.d/hdmi_sound.rulesvới quyền root với nội dung:

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

Lưu ý ACTION=="change", là thiếu!

Tạo một tệp /usr/local/bin/hdmi_sound_togglevới quyền root với nội dung:

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

Lưu ý USER_NAME =who | grep "(:0)" | cut -f 1 -d ' '| sort -u Tôi đã thêm| sort -uvì nếu không, nó đã quay lại vớielemer elemer elemer- tên người dùng 3 lần.

Sau đó làm cho nó thực thi được với chmod 0755 /usr/local/bin/hdmi_sound_toggle

Đừng quên tải lại các quy tắc udev của bạn: sudo udevadm control --reload-rules

Quan trọng kịch bản này được cập nhật cho 14.04. Trước đó, bạn sẽ sử dụng USER_NAME thay vì USER_ID ở mọi nơi

Tín dụng: Salemdaniel .


1

Ubuntu 16.04 - 17.04 Trả lời

Điều này hoạt động cho Ubuntu 16.04 - 17.04 đã giới thiệu một lỗi với Pulse Audio 8. Tạo tệp hotplugtv(hoặc hotplug-hdminếu bạn thích) và sao chép trong các dòng sau:

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

QUAN TRỌNG: Thay đổi tên người dùng "rick" thành tên người dùng của bạn.

Để gọi tập lệnh này udevtrong các sự kiện cắm nóng, hãy tạo tệp /etc/udev/rules.d/99-hotplugtv.ruleschứa:

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

Thay đổi /home/rick/bin/đường dẫn nơi bạn đặt hotplugtvtập lệnh.


Cảm ơn bạn rất nhiều! Nó cũng hoạt động trên Ubuntu 17.04! Điều này đã làm tôi khó chịu trong một thời gian dài và đó là một giải pháp đơn giản :)
Georgi Koemdzhiev

1
Bạn được chào đón nhất. Cảm ơn bạn đã bình luận xác nhận nó là cần thiết cho 17.04.
WinEunuuchs2Unix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.