Встановити звуковий сигнал HDMI автоматично при підключенні / відключенні


20

У мене на ноутбуці встановлено подвійний екран (використовуючи 12,04 LTS) за допомогою підключеного до HDMI дисплея. Все працює добре, але кожного разу, коли я підключаю / відключаю кабель, мені потрібно перейти до налаштувань звуку та змінити пристрій виведення звуку вручну.

Чи є спосіб змінити звуковий пристрій при підключенні / відключенні кабелю, тому при підключенні дисплея вихідний звук встановлюється на HDMI, а коли відключаю його, звук повертається до динаміків ноутбука?


Тут же проблема.
ThiagoPonte

Це перший раз, коли я приїхав сюди за будь-якою допомогою у цьому питанні ... Я в тому ж човні 12.10. Це дратує. З мого досвіду це було так з 10.10. Десь повинен бути конфігуратор, який може це впоратися. EDIT: voices.canonical.com/david.henningsson/2012/04/14/… Це встановлено таким чином. Це жахливо.
user138216

Перевірте, чи працює моя відповідь з вами.
Салем

Відповіді:


11

На користь людям, які натрапляють на це питання - рішення Салема майже спрацювало для мене в 13.04, я закінчив збирати шматочки та шматки з усієї мережі, я думаю, що для мене було уникнути угоди, це було відсутністю змінної середовища PULSE_SERVER

Ось моє повне рішення, яке в основному повторює рішення Салема з кількома відсутніми фрагментами. Я також повторно повторював його як сценарій оболонки (незважаючи на свою любов до Python), оскільки спершу я побоювався, що мій скрипт Python зіткнеться з проблемами шляху імпорту:


(те саме, що відповідь Салема) Створіть файл /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, тому що я там теж отримав "root" користувача - за рахунок того, що я редагував скрипт через kate, в якому був відкритий кореневий термінал.
Auspex

Продовжуйте отримувати "Помилка підключення: підключення відмовлено pa_context_connect () не вдалося: з’єднання відмовлено" під час запуску pactl. : \
Томіслав Накіч-Альфіревич

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))

Напевно, це можна легко зробити в баші, але оскільки моя основна мова - пітон, я використовував його. Все працює, окрім сповіщення: воно не з’являється, я дійсно не знаю чому. Якщо хтось знає, як це виправити, скажіть щось.

Примітка: імена правила script / udev можна змінити, але вам потрібно використовувати повний шлях.


3

Виходячи з Салема «S відповісти , і DANIEL відповідь» пд.ш.

Я взяв відповідь Салема та відповідь Даніеля і вніс необхідні зміни, їхнє рішення не спрацювало для мене поза коробкою:

(подібно до відповіді Салема).

Створіть файл /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--my ім'ям користувача 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! Це вже давно клопоче мене, і це було просте рішення :)
Георгій Коемджієв

1
Ти найбільш бажаний. Дякуємо за коментар, який підтверджує, що він також потрібен для 17.04.
WinEunuuchs2Unix
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.