Skip to content

Instantly share code, notes, and snippets.

@ties
Created August 29, 2013 17:20
Show Gist options
  • Save ties/6380889 to your computer and use it in GitHub Desktop.
Save ties/6380889 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# based on monitor-bluetooth
# Changes by Domen Puncer <domen@cba.si>
import gobject
import dbus
import dbus.mainloop.glib
import os, subprocess
import re
print("Starting bluetooth monitoring...")
DEVICE="alsa_output.usb-Burr-Brown_from_TI_USB_Audio_DAC-00-DAC.analog-stereo"
"""
"""
def loopback_modules():
cmd = ["sudo", "-u", "pi", "pactl", "list", "modules", "short"]
res = subprocess.check_output(cmd)
# non-empty lines in result
for line in [line.strip() for line in res.split("\n") if line.strip()]:
groups = re.match("(?P<id>[0-9]+)\s+module-loopback\tsource=bluez_source\.(?P<mac>[\w]{17}) sink=.*", line)
if groups:
yield groups.group("id"), groups.group("mac")
# we want this event: {AudioSource.PropertyChanged} [/org/bluez/16797/hci0/dev_00_24_7E_51_F7_52] State = playing
# and when that happens: pactl load-module module-loopback source=bluez_source.00_24_7E_51_F7_52 sink=alsa_output.pci-0000_00_1b.0.analog-stereo
def property_changed(name, value, path, interface):
iface = interface[interface.rfind(".") + 1:]
val = str(value)
print("{{{}.PropertyChanged}} [{}] {} = {}".format(iface, path, name, val))
# continue and add new module
bt_addr = "_".join(path.split('/')[-1].split('_')[1:])
if iface == "AudioSource" and name == "State" and val == "playing":
# check if there already is a module for this mac:
if bt_addr in [mac for pos, mac in loopback_modules()]:
print("Loopback module already loaded for {}.".format(bt_addr))
return
# build command, run as user pi
cmd = ["sudo", "-u", "pi",
"pactl", "load-module", "module-loopback",
"source=bluez_source.{}".format(bt_addr), "sink={}".format(DEVICE)]
module_nr = subprocess.check_output(cmd)
print("Loaded loopback for {} with module #{}.".format(bt_addr, module_nr))
elif iface == "AudioSource" and name == "State" and val == "disconnected":
# disconnection, find index, unload-module
for (pos, mac) in loopback_modules():
if mac == bt_addr:
res = subprocess.check_output(["sudo", "-u", "pi", "pactl", "unload-module", pos])
print("Cleaned index {}, result: {}.".format(pos, res))
def object_signal(value, path, interface, member):
iface = interface[interface.rfind(".") + 1:]
val = str(value)
print("{{}.{}} [{}] Path = {}".format(iface, member, path, val))
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
bus.add_signal_receiver(property_changed, bus_name="org.bluez", signal_name = "PropertyChanged", path_keyword="path", interface_keyword="interface")
mainloop = gobject.MainLoop()
mainloop.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment