linux 下搞定蓝牙耳机

其实今天在 linux 下面搞定蓝牙耳机并不是很难的事情。只不过因为这个问题在历史上曾经比较棘手,网上充斥了大量相对陈旧的、复杂的安装指南,导致人们一直感觉这样时尚的东西,可能 linux 支持起来很复杂。而实际上可能并不是这样。

linux 上的蓝牙部分,是 bluez 的项目来实现的。因此,只要紧盯 bluez 的官方网站,就可以获得最新、最权威的指导。比如搞定蓝牙耳机,基本上就只要参考官方 wiki 的这篇文章就可以搞定。如果更偷懒一些,这篇 blog 里的脚本也是 “拆箱即用”,方便的很。

相比之下,archlinux wiki 上的文章就相对陈旧。这里不得不佩服 gentoo,文档方面真是一流,从过去到现在,虽然写在一起有点杂乱,但是信息量很足。

最后奉上一点拙作,这是和之前那篇 blog 功能一样的一段脚本,不过不依赖 python,只要有 bash 就行(blogspot 的引用段落会打乱排版,如果自己加了 <pre> 标签,又有可能造成某些长行看不见,所以暂时就贴成这样了,还请见谅)。

#!/bin/bash

if [ $1 ]; then
ACTION=$1
else
ACTION="off"
fi

MAC="00:11:22:33:44:55" # your bluetooth device's mac

if [ "$ACTION" == "music" ]; then

echo Connect bluetooth headset in stereo mode

# active service
TMP=`dbus-send --system --print-reply --dest=org.bluez /org/bluez org.bluez.Manager.ActivateService string:audio`
DEST=`expr match "$TMP" '.*\(\".*\"\)'`
DEST=${DEST#\"}
DEST=${DEST%\"}

# create device
TMP=`dbus-send --system --type=method_call --print-reply --dest=$DEST /org/bluez/audio org.bluez.audio.Manager.CreateDevice string:$MAC`
DEV_PATH=`expr match "$TMP" '.*\(\".*\"\)'`
DEV_PATH=${DEV_PATH#\"}
DEV_PATH=${DEV_PATH%\"}

# connect
dbus-send --system --type=method_call --print-reply --dest=$DEST $DEV_PATH org.bluez.audio.Sink.Connect

# for gstreamer
gconftool-2 --type string --set /system/gstreamer/0.10/default/musicaudiosink "alsasink device=bluetooth"

echo done.

elif [ "$ACTION" == "voice" ]; then

echo Connect bluetooth headset in voice mode

# active service
TMP=`dbus-send --system --print-reply --dest=org.bluez /org/bluez org.bluez.Manager.ActivateService string:audio`
DEST=`expr match "$TMP" '.*\(\".*\"\)'`
DEST=${DEST#\"}
DEST=${DEST%\"}

# create device
TMP=`dbus-send --system --type=method_call --print-reply --dest=$DEST /org/bluez/audio org.bluez.audio.Manager.CreateHeadset string:$MAC`
DEV_PATH=`expr match "$TMP" '.*\(\".*\"\)'`
DEV_PATH=${DEV_PATH#\"}
DEV_PATH=${DEV_PATH%\"}

# connect
dbus-send --system --type=method_call --print-reply --dest=$DEST $DEV_PATH org.bluez.audio.Headset.Connect

# play
dbus-send --system --type=method_call --print-reply --dest=$DEST $DEV_PATH org.bluez.audio.Headset.Play

echo done.

elif [ "$ACTION" == "off" ]; then

echo Turn bluetooth headset off
gconftool-2 --type string --set /system/gstreamer/0.10/default/musicaudiosink "autoaudiosink"

else

echo Usage: $0 music/voice/off
echo default action is off

fi


p.s. 作为脚本来讲,python 真的很方便,用 bash 写起来要费力的多。那个去掉引号的部分,折腾了我两个小时。

最后,我的蓝牙耳机上的 mic 还没搞定(也就是说,上述 voice 部分不保证有效),如有高人路过恳请赐教,谢谢!

评论

匿名说…
您好,我叫做阿欽,剛好最近有在接觸bluetooth的東西,想請問你一些相關的問題
我最近使用A2DP藍芽耳機聽音樂,作業系統Ubuntu,在聽的過程中,假如藍芽中斷(不管是電腦中斷或是耳機中斷),正在播放的播放器就會當掉,我是用banshee的(播放器),因為不曉得問題 是在Bluetooth這邊還是在播放器的問題還是本身OS聲音切換的問題??
還有說藍芽斷線沒有告知播放器所以播放器會當掉,我除了l2ping這個可以得知藍芽已經斷線之外,是否有其他的方式可以得知連線藍芽已斷線了,進而可以再想辦法通知播放器,謝謝
Li Ruibo说…
蓝牙的音频连接,实际上应该就是蓝牙网络通信。目前来看,通信链路出现问题的话,多数应用程序都是不断的重新发送,使用者看起来就是应用程序失去响应,CPU 占满这类现象。至于这种容错失败的环节具体是在应用程序这边还是在 bluez 上,我还真说不清楚。