Description
This page contains audio service usage examples. The API description is available at audio service.
Note that there are a few approaches for a2dp (alsa, gstreamer, pulse?), maybe two for sco (alsa, pulse?). Alsa is the simplest and should support the greater variety of audio clients directly.
Basic steps
(these are valid for bluez-utils-3.16 or newer)
Note: you will not need bluetooth-alsa, plugz, btsco or the like for audio to work. They are obsolete.
- Make sure the audio service is installed
- modify your ~/.asoundrc to contain
pcm.bluetooth { type bluetooth device 00:11:22:33:44:55 }where 00:11:22:33:44:55 is the Bluetooth address of your headset (use for example hcitool scan to find it) - configure your audio application to use the alsa device "bluetooth". See Supported Players for some examples.
- start playing :)
Tips
- There's a tool called dbus-viewer (apt-get install dbus-viewer; dbus-viewer --system) which is very helpful in using D-Bus interfaces as long as there are no convenient scripts or GUIs available for them. A newer similar tool for GTK+ is called D-Feet.
Known issues
- You may get choppiness with a2dp. An hcid.conf with "lm accept,master;" and "lp hold,sniff,park;" will be more robust.
- If you get messages in the kernel log like "sco packet for unknown connection" then you may need to apply a kernel patch (several versions of the fix are circulating around bluez-dev but no one solution seems right)
- xmms with broadcom based headsets produces choppy sound at times (actually xmms in general seems to have a little bit buggy alsa usage). We recommend using some other player, e.g. audacious.
- e.g. the Logitech freepulse and Etymotic Research ety8 headphones are broadcom based
- vlc pause/unpause doesn't work (no sound after unpause)
Alsa Plugin
Configuration
Append this lines to ~/.asoundrc:
pcm.bluetooth {
type bluetooth
device "XX:XX:XX:XX:XX:XX" #optional, connects to specific device instead the default one
profile "auto" #optional, supported profiles are: auto, hifi and voice
}
Supported Players
aplay and arecord
arecord -D bluetooth -f S16_LE | aplay -D bluetooth -f S16_LE
gst-launch
gst-launch -v alsasrc device=bluetooth ! audioconvert ! audioresample ! alsasink device=bluetooth sync=false
audacious
options->preferences->Audio->Current Output Plugin->ALSA Output Plugin Preferences->Device Settings->audio device: "bluetooth"
if you can't see the audio device form there, you can force the bluetooth output by modifying your audacious property file
~/.config/audacious/config. Modify the "pcm_device" value by "pcm_device=bluetooth"
xmms
xmms is known to have some issues, please use its successor audacious instead
options->preferences->Output Plugin->Configure: "bluetooth"
beep-media-player
preferences->Plugins->Output->Select ALSA->Preferences->Audio device: "bluetooth"->Advanced->disable mmap mode
mplayer
mplayer -ao alsa:device=bluetooth
play
play --device=bluetooth file.mp3
amarok
Amarok configuration -> Engine -> Select: "alsa" then replace "default" with "bluetooth" in either "mono" or "stereo" field
banshee, rhythmbox and totem
to route the sound to bluetooth:
gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "alsasink device=bluetooth"
to route the sound to normal speakers:
gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "autoaudiosink"
Kaffeine
Menu Settings -> xine Engine Parameters -> audio -> Expert Options tab Change "device.alsa_default_device" (mono) and "device.alsa_front_device" (stereo) from "default" to "bluetooth"
GStreamer Plugin
Currently only available for a2dp.
Configuration
It is not necessary to create a virtual device as in alsa, configuration can be change via element properties:
a2dpsink
Element Properties:
name : The name of the object
flags: readable, writable
String. Default: null Current: "a2dpsink0"
preroll-queue-len : Number of buffers to queue during preroll
flags: readable, writable
Unsigned Integer. Range: 0 - 4294967295 Default: 0 Current: 0
sync : Sync on the clock
flags: readable, writable
Boolean. Default: true Current: true
max-lateness : Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited)
flags: readable, writable
Integer64. Range: -1 - 9223372036854775807 Default: -1 Current: -1
qos : Generate Quality-of-Service events upstream
flags: readable, writable
Boolean. Default: false Current: false
device : Bluetooth remote device address
flags: readable, writable
String. Default: null Current: null
sbcenc
Element Properties:
name : The name of the object
flags: readable, writable
String. Default: null Current: "sbcenc0"
mode : Encoding mode
flags: readable, writable
Enum "GstSbcMode" Current: 0, "auto"
(0): auto - Auto
(1): mono - Mono
(2): dual - Dual Channel
(3): stereo - Stereo
(4): joint - Joint Stereo
allocation : Allocation mode
flags: readable, writable
Enum "GstSbcAllocation" Current: 0, "auto"
(0): auto - Auto
(1): loudness - Loudness
(2): snr - SNR
blocks : Blocks
flags: readable, writable
Integer. Range: 0 - 2147483647 Default: 0 Current: 0
subbands : Sub Bands
flags: readable, writable
Integer. Range: 0 - 2147483647 Default: 0 Current: 0
Supported Players
gst-launch
gst-launch -v ... ! decodebin ! audioconvert ! audioresample ! sbcenc ! a2dpsink device=XX:XX:XX:XX:XX:XX
banshee, rhythmbox and totem
to route the sound to bluetooth:
gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "sbcenc ! a2dpsink device=XX:XX:XX:XX:XX:XX"
to route the sound to normal speakers:
gconftool -t string -s /system/gstreamer/0.10/default/musicaudiosink "autoaudiosink"
Trying pulse
This is unproven but might not be far off.(it´s work)
Make audio service autostart. (Autostart=true in /etc/bluetooth/audio.service)
.asoundrc:
pcm.headset {
type bluetooth
device "XX:XX:XX:XX:XX:XX"
profile "voice"
}
Manually run:
pactl load-module module-alsa-sink device=headset pactl load-module module-alsa-source device=headset
Then use pavucontrol to make the headset sink/source the default
Advanced examples for programatically setting up audio devices
The examples from here to the end of the page are only for programmers who need to automate device creation, service startup, etc. Stop reading now if you're just trying to get the basics working.
Service Activation
When a client wants to start the audio service or discover the audio service bus "id", the ActivateService method should be called.
import dbus
bus = dbus.SystemBus()
bmgr = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager')
bus_id = bmgr.ActivateService('audio')
# All serial service messages should be sent to this address
print bus_id
Service activation from command line:
$dbus-send --system --type=method_call --print-reply --dest=org.bluez \ /org/bluez org.bluez.Manager.ActivateService string:audio
A2DP
A2DP (Advanced Audio Distribution Profile) is intended for high quality stereo audio applications.
For A2DP there is no need to specifically request a "playing" state. The bluetooth alsa plugin will automatically do this when some application tries to use it. If no device is connected, the default device will be connected to, otherwise the first found connected device will be used.
python
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager')
bus_id = manager.ActivateService('audio')
audio = dbus.Interface(bus.get_object(bus_id, '/org/bluez/audio'), 'org.bluez.audio.Manager')
path = audio.CreateDevice('00:11:22:33:44:55')
#audio.ChangeDefaultDevice(path) #change the device to be used by default
sink = dbus.Interface (bus.get_object(bus_id, path), 'org.bluez.audio.Sink')
sink.Connect()
Command line
The ":X.Y" in the following examples is the unique bus name of the audio service. You get it in the reply to the ActivateService method call:
$dbus-send --system --print-reply --dest=org.bluez /org/bluez org.bluez.Manager.ActivateService string:audio
* CreateDevice:
$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \ /org/bluez/audio org.bluez.audio.Manager.CreateDevice string:00:11:22:33:44:55
* Connect (replace device_object_path with return value from last call):
$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \ "device_object_path" org.bluez.audio.Sink.Connect
Headset Profile
The Headset Profile is intended for two-way low-latency audio applications such as VoIP.
python
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager')
bus_id = manager.ActivateService('audio')
audio = dbus.Interface(bus.get_object(bus_id, '/org/bluez/audio'), 'org.bluez.audio.Manager')
path = audio.CreateHeadset('00:11:22:33:44:55')
#audio.ChangeDefaultHeadset(path) #change the device to be used by default
headset = dbus.Interface (bus.get_object(bus_id, path), 'org.bluez.audio.Headset')
#Connect and Play are not required in PCM mode
headset.Connect()
headset.Play()
Command line
* CreateHeadset:
$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \ /org/bluez/audio org.bluez.audio.Manager.CreateHeadset string:00:11:22:33:44:55
* Connect:
$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \ "device_object_path" org.bluez.audio.Headset.Connect
* Play:
$dbus-send --system --type=method_call --print-reply --dest=":X.Y" \ "device_object_path" org.bluez.audio.Headset.Play
