colaghost

自己的世界。。。

ubuntu下自动切换声音输出设备

我有一个usb耳机,在ubuntu下驱动也正常,不过有一个蛋疼的地方就是每次插进usb耳机都不会自动切换到usb耳机对应的声音输出设备,次次都要手动去选择对应的,于是想着能不能写一个脚本来实现。
不过貌似关于这方面的中文资料不多,google了很久都没有什么结果,倒是找出一个freebsd上能实现的,就是sysctl,不过貌似ubuntu下实现不了。后来在stackoverflow上问老外才得知用pacmd可以列出各种可用的声音输出设备还有设置默认输出设备等操作神马的。
弄了一下,果真OK了,写随意写了一个脚本来测试了,这个脚本假设系统使用pulseaudio的。
原理也不难,就是检测所有的声音设备,找出当前默认的声音设备,然后把声音设备切换到下一个,重新运行脚本就可以把声音设备切换回原来默认的了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
 
declare -i count=`pacmd list-sinks | grep -c index:[[:space:]][[:digit:]]`
declare -i active=`pacmd list-sinks | sed -n -e 's/\*[[:space:]]index:[[:space:]]\([[:digit:]]\)/\1/p'`
declare -i major=$count-1
declare -i next=0
 
if [ $active -ne $major ] ; then
next=active+1
fi
 
pacmd "set-default-sink ${next}"
 
for app in $(pacmd list-sink-inputs | sed -n -e 's/index:[[:space:]]\([[:digit:]]\)/\1/p');
do
pacmd "move-sink-input $app $next"
done
 
declare -i ndx=0
pacmd list-sinks | sed -n -e 's/device.description[[:space:]]=[[:space:]]"\(.*\)"/\1/p' | while read line;
do
if [ $next -eq $ndx ] ; then
notify-send -i notification-audio-volume-high "声音输出切换到" "$line"
exit
fi
ndx+=1
done;

脚本里在切换后会做notify-send的提示,假设找不到命令的可以执行sudo apt-get install libnotify-bin安装一下,但不安装也没有什么关系,只是一个提示而已。

为了方便可以将脚本复制到/usr/bin目录下,然后在“键盘快捷键”里面添加多一个快捷键,命令就是脚本名了,最后设定好想要的快捷键,以后就可以直接切换了。

关于mediastreamer和pulseaudio的那点破事

这些天的一些开发涉及到mediastreamer等几个开源包,之前一直是用跑在虚拟机上的redhat。无奈问题多多,测试程序音质很差,两台机之间的音频通信更是无法忍耐,延时很严重,还老是有杂音,一说快就完全听不清楚了。心想可能是系统跑在虚拟机上的关系吧,记得程序总会爆出警告。加上也想换到ubuntu10.04过下瘾,就直接安装上了。

满怀期待地换上了,把几个包都编译好。试了下用ring_start来播放*.wav文件,倒也没有延时了。再试下开源包自带的echo这个例子,无奈问题来了,貌似采集不到声卡的数据,没有音频输出。看了一下程序的输出报告,只有OSS,却没有ALSA。怪了啊,UBUNTU默认应该只有ALSA的啊,怎么会只有OSS的呢?

不管那么多了,升级下声卡驱动吧,看看问题能不能解决!折腾了半天把驱动更新完,并用gnome-alsamixer做了一些改动,好,以失败告终,除了杂音大点外无任何副作用!

最后跑到群上问,有一大牛才相告程序找到的oss是pulse-oss-plugin,而且所有音频输出由pulseaudio接管,但底层还是基于alsa的。以为是mediastreamer2这个开源包不支持pulseaudio,可是搜了下人家明明白白写着是支持的。阅读了一下关于这点的源代码,也确实有提供了pulseaudio的支持。既然这样的话应该还有pulseaudio的才对啊,怎么会只有OSS呢?再次试着configure整个开源包,突然看到了一句,“checking for LIBPULSE… no”!一切问题出来了,少了个pulse的静态开发库。上新立德搜了个,安装后,运行echo时手动指定声卡为pulseaudio。出声了,折腾了一天的问题竟然就出在这个小点上。可能是mediastreamer2依赖于这个库的一些调用,当缺少这个库时,开发包预编译时就会认定没有pulseaudio而直接把相关源码略过。