我在笔记本电脑上使用HDMI连接的显示器在双屏幕设置(使用12.04 LTS)上进行了设置。一切正常,但是每次连接/断开电缆时,都必须转到“声音”偏好设置并手动更改声音输出设备。
是否可以通过电缆的连接/断开来更改声音输出设备,所以当我连接显示器时,声音输出设置为HDMI,而当我断开连接时,声音返回到笔记本电脑扬声器吗?
我在笔记本电脑上使用HDMI连接的显示器在双屏幕设置(使用12.04 LTS)上进行了设置。一切正常,但是每次连接/断开电缆时,都必须转到“声音”偏好设置并手动更改声音输出设备。
是否可以通过电缆的连接/断开来更改声音输出设备,所以当我连接显示器时,声音输出设置为HDMI,而当我断开连接时,声音返回到笔记本电脑扬声器吗?
Answers:
为了让那些偶然发现此问题的人受益-塞勒姆的解决方案在13.04中几乎对我有用,我最终从网络上收集了点点滴滴,我认为对我而言,最关键的是缺少环境变量PULSE_SERVER
这是我的完整解决方案,基本上是重复了Salem的解决方案,但缺少了一些内容。我也将其重命名为shell脚本(尽管我对Python情有独钟),因为起初我担心我的Python脚本会遇到导入路径问题:
(与Salem的答案相同)创建一个/etc/udev/rules.d/hdmi_sound.rules
具有以下内容的root用户文件:
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时删除了关键字“ export”时,脚本对我而言失败了,我认为pactl正在寻找env变量
不要忘记重新加载udev规则: sudo udevadm control --reload-rules
更新此脚本已针对14.04更新。在此之前,您将在各处使用USER_NAME而不是USER_ID
| uniq
到USER_NAME命令。另请注意,Ubuntu中的声音设置可能会欺骗。我没有在声音设置面板中看到更改,但是一旦播放了某些内容,音频就会平稳地来回切换,我还注意到在插入和拔出HDMI几次后,脚本停止运行了(也许有些udev中的错误)。
| sort -u
了用户名,因为它说的是额外的选项elemer elemer ---我的用户名。最终与FuegoFro的解决方案相同。
| grep -v pts
,因为我实际上是通过kate编辑脚本的,所以实际上我在那里也有一个“ root”用户,因为kate打开了root终端。
我终于设法使用来完成这项工作udev
。因此,如果有人想要相同的行为,请执行以下步骤:
首先,我们需要创建一个/etc/udev/rules.d/hdmi_sound.rules
包含以下内容的文件:
SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"
每当HDMI连接发生变化时,这将使udev
脚本执行hdmi_sound_toggle
。该脚本必须具有执行权限,其内容如下:
#!/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))
可能可以轻松地在bash中实现,但是因为我的主要语言是python,所以我使用了它。除通知外,其他所有方法都有效:它没有显示,我真的不知道为什么。如果有人知道如何解决,请说些什么。
注意:脚本/ udev规则的名称可以更改,但是您需要使用完整路径。
我接受了Salem的回答和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
这适用于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
脚本的路径。