-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bluetooth Media Control and display #61
Comments
UpdateI found some resources for what to do with the bluetooth stack:
Getting data about playbackimport dbus
#XX_XX_XX_XX_XX_XX is a placeholder for bt mac adress of connected device
#probs dict should yield same results as terminal command but in more structured format
#qdbus --system org.bluez /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/player0
bus = dbus.SystemBus()
player = bus.get_object("org.bluez", "/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/player0")
BT_Media_iface = dbus.Interface(player, dbus_interface="org.bluez.MediaPlayer1")
BT_Media_probs = dbus.Interface(player, "org.freedesktop.DBus.Properties")
probs = BT_Media_probs.GetAll("org.bluez.MediaPlayer1")
print(probs) Control PlaybackAnd this command for skipping the current song dbus-send --system --type=method_call --dest=org.bluez /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/player0 org.bluez.MediaPlayer1.Next The last word in the value can be:
as found in the reddit question. I'm not that familiar with dbus so I couldn't figure out yet how to send the commands with the python library. Now the thing I'm unsure with is how to integrate the metadata into the extisting rds services and the commands into the button service to use when BT is connected. |
also just saw #29 . info here should help with this issue |
Hello! First of all, thanks for your interest, second, there are so many good informations here, I'll have to read through them carefully when I get a slot of free time. Also, I wouldn't worry too much about integrations if I were in you, because I've got a good news as well: I'm thinking about re-writing the whole project in python, it would be much easier to integrate, and right now the project suffers from a variety of reliability inconsistencies when it comes to bluetooth audio playback (for some works, for others don't) probably due to it relying on system and bash scripts for detecting new devices upon connection. |
That's some good news as python is my preferred language. I'd like to help as far as I can. Do you have any plan when you want to start the rewrite? |
I got a working script to control BT media playback. It does not do anything for local playback as I only use bluetooth but it seems to work. How to use
Codeimport RPi.GPIO as GPIO
import time
from subprocess import check_output, call
import re
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def get_mac():
device_cmd = "bt-device -l"
result = check_output(device_cmd, shell=True)
regex = "[(].*[)]"
mac = re.findall(regex, result)[0]
#print(mac)
return mac.replace(":","_").replace("(","").replace(")","")
#TODO refactor for less code repetition to just alter print and last command
last_play = True
def pause():
cmd_arr = ["dbus-send", "--system" , "--type=method_call", "--dest=org.bluez", "/org/bluez/hci0/dev_" + get_mac() + "/player0", "org.bluez.MediaPlayer1.Pause"]
global last_play
if last_play == False:
print("Play")
cmd_arr[5] = "org.bluez.MediaPlayer1.Play"
else:
print("Pause")
#inverse last play after command
last_play = not last_play
call(cmd_arr)
def skip():
print("skip")
global last_play
last_play = True
cmd_arr = ["dbus-send", "--system" , "--type=method_call", "--dest=org.bluez", "/org/bluez/hci0/dev_" + get_mac() + "/player0", "org.bluez.MediaPlayer1.Next"]
call(cmd_arr)
def previous():
print("previous")
#spotify start playing on previous command so removed
#global last_play
#last_play = True
cmd_arr = ["dbus-send", "--system" , "--type=method_call", "--dest=org.bluez", "/org/bluez/hci0/dev_" + get_mac() + "/player0", "org.bluez.MediaPlayer1.Previous"]
call(cmd_arr)
def shutdown():
print('shutdown')
call(["killall", "mpradio"])
call(["killall", "sox"])
call(["shutdown", "-h", "now"])
time.sleep(10)
state = True
max_delay = 1
shutdown_push_time = 5
last_time = time.time()
pulse_count = 0
while True:
new_state = GPIO.input(18)
if new_state == False and state == False and (time.time() - last_time) > shutdown_push_time:
#if button is still pressed after 5 seconds shutdown device
shutdown()
if new_state == False and state == True: #going from off to on
pulse_count += 1
state = new_state
last_time = time.time()
elif new_state and state == False: #on to off
state = True
if time.time() > (last_time + max_delay) and pulse_count > 0: #too long a delay so after end of sequence
if pulse_count == 1:
pause()
elif pulse_count == 2:
skip()
elif pulse_count == 3:
previous()
else:
pause()
pulse_count = 0 |
@DavidM42 I can't make precise schedule at the moment because everything's so "dynamic" in this period, but I probably would start with the bluetooth a2dp part to see if it makes sense. |
Nice. Seems good. pi_fm_adv should be the go to. From my testing it produces much better quality than the other driver. |
@DavidM42 have a look at |
It's been a while since I've poked around on this, but I think I'll throw my hat into the ring this weekend. I am not the strongest Python coder, but I love the ideas you put together in that diagram @morrolinux, so I should be able to help cobble something together if you want to cooperate on a python branch. Python also means we can rely on stronger |
@DavidM42 nice discoveries RE: AVRCP! I'd tried but failed to scratch that itch a while ago :( I'll see what I can do to help now :) |
@Hurricos Cool! since the last schematic I've changed the design just a bit on the remote controller part, but overall that's the thing. I'll update the schematic soon. This afternoon I'm going to open a new repo on github to share the current progress. (spoiler: core functionalities are already working!) :) |
@Hurricos I've published a new repo for the python version here |
@DavidM42 same for you of course :) |
I've got a few questions about the rewrite.
And concerning bluetooth rds I'm facing a bit of a non technical problem. I couldn't find any radio which has rds info besides the car but I won't be debugging on a pi in a car :D |
I created a rough draft for the id3 tag reading. Was easy to implement thanks to the nice library mutagen it's in my fork here |
And regarding my pushbutton script. I tested it a few times in the last days and the recognition of pushes does not quite work as wanted. Double clicking leads to a skip and then pause -> the timing probably needs to probably be edited for it to be usable. |
Well I haven't set a requirement as of yet, but of course it must run on Raspbian 9 which comes with python 3.5 so if it runs on it, it's fine to me. Portability on other platofrms is not really a need because of hardware constraints in FM transmission with PiFmAdv.
I'm not a big expert on licenses, so I guess anything different from GPL will have to be checked for requirements for integration in the project. But I guess it should generally be fine if we link it in the README. As few dependencies as possible is always a nice goal to acheive, unless it results in the code being utterly convoluted and unnecessarely complicated... then I would say who cares, let's not make it an unreadable mess.
I'm not really sure what you mean by that. As of now, no non-standard python libraries are being used and I'm not using a python environment. If you run mpradio.py on your computer, it will play "storage" files on speakers instead of attempting to stream on FM
Oh but don't worry about that, it will probably won't be needed. I'll put the basis for the RDS updater module and running it on something that's not a Raspberry Pi will just print out RDS info to the screen so that we'll all be able to work comfortably |
Cool. I would start with a requirements.txt just because we're in a really early stage of the work, then make it a module with the very first release, but really, if you start to work on the setup.py I won't say no |
Are you using a pre-built mpradio image? or maybe you're running on raspbian 9 with the "classic" mpradio installed? because it has lots of systemd unit dependencies and it doesn't really work out to be fast. With mpradio-py I would only check for the bluetooth interface to be available and let
Most likely yes. But again, now I think you're working on the "classic" mpradio. Here we should start from scratch |
@DavidM42 I'm waiting for your PR about id3 data the new repo, which has now a skeleton to be placed to |
So first of all thanks for this really cool project.
The only two things I'm still missing from this is the possibility to skip songs/pause on a bt client player device (like a phone) and the forwarding of the currently playing track into rds.
I've done some reasearch because I'd like to help integrating them via PR but I don't understand the project enough for now.
The thing needed for this is probably the AVCRP protocol to control media playback and get more info from apps integrating into this protocol on phones. I found out that you can access this information/send info to bluez via the dbus but I could not get it done myself (partly because of bluez documentation beeing sparse). Does anybody know more about this topic?
The text was updated successfully, but these errors were encountered: