Переключение на HDMI Audio, когда HDMI подключен к ноутбуку (14.04)

12

Я пытаюсь заставить свой ноутбук переключать звук на HDMI, когда он подключен, и обратно на стандартный аналоговый, когда он удален.

Я установил правило udev для запуска сценария, чтобы выполнить переключение, однако у меня возникают проблемы с его работой:

  • Похоже, что до тех пор, пока я не выберу выход HDMI Audio в настройках звука, он не будет распознан как доступный приемник, также после выбора выхода HDMI Audio аналоговый выход больше не отображается.

Смотрите ниже:

# 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 в настройках звука.

Kingamajick
источник
2
Некоторое время тому назад была похожая тема: http://askubuntu.com/questions/317762/is-it-possible-to-automatics-switch-to-hdmi-sound-output-13-04 Ссылка на обсуждение здесь: http : //lists.freedesktop.org/archives/pulseaudio-discuss/2012-March/013009.html
РРР

Ответы:

9
  1. Проверьте наличие доступных карт и профилей

    pactl list cards
    
  2. Добавьте следующую команду в скрипт, чтобы сменить профиль перед установкой приемника по умолчанию и движущихся потоков.

    pactl [options] set-card-profile  CARD PROFILE
    

(Так что нет необходимости переключать его вручную из настроек звука)

Ссылка:

pactl -h & man pactl

user.dz
источник
9

Основываясь на этой ссылке и этой ссылке ... я проверил и работает прекрасно 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

Я надеюсь, что может помочь .. извините за мой английский, я говорил по-испански

Пестрый
источник
4

У меня была небольшая проблема после этого. Я скопировал оригинальный скрипт и изменил его, как предложено, и теперь он работает.

Я включил это здесь, чтобы облегчить кому-то еще использование.

#!/bin/bash
## From: /ubuntu/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, но я не знаю, как это сделать.

Джо
источник
1
Это не работает в 16.04. Я снова работаю над этим.
Джо
3

Предоставленные мной скрипты не работали с udev из коробки на Ubuntu 14.04, я должен был добавить:

export DISPLAY=:0

вначале преобразуйте две команды pacmd в pactl и, наконец, запустите скрипт, используя sudo -s -u (user) из правила udev.

#!/bin/bash
## From: /ubuntu/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
кругозор
источник
2

Ну, все предоставленные скрипты не работали для меня (Ubuntu 16.04), но я нашел этот индикатор приложения, который позволяет вам изменять вывод звука всего одним щелчком мыши:

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

(примечание: вам необходимо установить пакет appindicator первым: sudo apt-get install python-appindicator)

Просто подумал, что оставлю это здесь для тех, кто может оказаться в той же ситуации, что и я, хотя это альтернативное решение ... но оно делает его довольно простым и дискретным ;-)

Нат Азоднем
источник
0

Опять же, другое решение (проверенное на работоспособность в 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

Связанная суть здесь .

Тревиньо
источник
У меня был похожий сценарий, который работал с использованием, card0но однажды он переключился на, card1поэтому я изменил сценарий, а на следующий день он изменился обратно card0. В конце концов я изменил код на card*и все хорошо с тех пор. Просто один на один, если что-то подобное случится с тобой.
WinEunuuchs2Unix
0

Сценарии Udev запускаются от имени пользователя root, но вы также должны знать, какой менеджер дисплея вы используете. Эти сценарии должны работать, но вы должны авторизовать этот менеджер дисплеев, чтобы сделать это.

Найдите DM, который вы используете:

pgrep -a Xorg

Посмотрите опцию -auth, она покажет вам менеджер дисплея. Это может быть sddm ou lightdm в последних выпусках Ubuntu.

Эта строка должна быть экспортирована как переменная 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 и сделать сценарий исполняемым.

LinuxHelper
источник