humarf writes

Hello,

using upmpdcli and songcast features for a long time. I’m also using external audio sources to distribute them via songcast - working very well. Do you see a chance to create an input source that reads audio data streamed via bluetooth from e.g. a tablet?

Best regards humarf

medoc92 writes

I really know nothing about bluetooth… I guess that you will have to look up what protocols, drivers and libs are used for this, and see if there is a way to capture the stream. I guess that if this is possible you should then be able to use it like the output of arecord ?

humarf writes

Unfortunately I know nothing about bluetooth as well. Now by accident I found this promising piece of software: https://github.com/Arkq/bluez-alsa I guess this could be used creating an input source for the songcast script.

medoc92 writes

I’ll be interested by the results if you want to give it a try !

humarf writes

Tried to get it running on my desktop PC.

I installed bluez and bluez-alsa. Each package provides a service that needs to be started. Then it took a while to find out how devices can be paired. Managed it using bluetoothctl provided by bluez package. When pairing my mobile phone desktop PC announced itself as audio sink.

After that I could play audio on my phone and it was streamed via bluetooth but I could hear nothing. I was a bit confused because arecord -L did not show any additional device but I tried and piping arecord to an aplay command worked anyway - so I could hear sound streamed from my phone.

After that I created a new input "Bluetooth" for upmpdcli. File device-Bluetooth has to look like this:

bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp

After restarting upmpdcli I could connect from my phone select Bluetooth input and hear streamed sound. Of course this could also be distributed to other upmpdcli renderers in my network.

Now I have to test if this also works on my raspberryPi renderer but so far this is very promising :-D

medoc92 writes

Yes, this looks very useful. It would be nice if I could add a description of this to the upmpdcli documentation (either host it or point to an external page if you want to put one up), if you are willing to write a recipe, this looks like it could be useful to other people.

humarf writes

Will do when I have it finally running. So far I’m making good progress. I can say that it even works on a first genaration raspberry pi.

There is an issue that I am facing now that might be related to a misconfiguration of my upmpdcli. I hope you can give me a hint how to change this. When playing via bluetooth on the local machine upmpdcli switches to songcast receiver mode. Volume control in receiver mode has no effect at the moment. Any idea what I could have done wrong?

Second thing is that I have two use cases in mind. First is to be able to stream audio into the OH-system - this what is already (near final :-) set up. Second use case would be that when e.g. watching a video on the tablet I would like to be able to play it’s sound via bluetooth connected device. Going songast sender/receiver way would mean that audio and video are not synced anymore. Bluez-alsa includes a playback binary that simply forwards audio stream to a local audio output of the pi (in fact it’s a wrapper for an arecord ...| aplay command). Do you see a chance to create a second bluetooth input source that does not set up songcast but calls a given binary for local playback?

medoc92 writes

I think that you can’t control the volume through upmdpcli in this situation, because the "real" mpd is not active (it’s the one upmpdcli would talk to for volume control). See this fig:

(In your situation the "aux MPD" is replaced by the script, but neither touches ALSA).

The one process which touches Alsa, sc2mpd, has no interface for volume control. So I think that the 2 possible approaches are to scale the original stream or use an external mixer control. Actually, maybe the upmpdcli volume control scripts feature would be usable for this. See externalvolumecontrol in there: https://www.lesbonscomptes.com/upmpdcli/upmpdcli.html

About the second question, no, the source control interface is already too complicated. Out of curiosity, how much delay do you see when going through songcast ?

humarf writes

The delay is about a second. For watching video it’s a bit too much.

I have modified input script that it detects address of connected bluetooth device automatically and plays from that one.

I also played around a bit with your input script to get direct playback. Commenting out senderproc and replacing recordproc with buealsa-aplay command helps playing directly from bluetooth input. Of course I cannot calculate correct uri and metadata for upmpdcli. But sending some fake information like that: print("Ok 0 URI XXX== METADATA YYY==") lets sc2mpd crash but without any negative effect on upmpdcli. Volume control still works and I can change back to another input source when finished.

Will try out external volume feature that you advised for bluetooth input next.

PhyberApex writes

@humarf Do you have anything you can provide so far? I am completly new to this and would very much like a little write up from you what you did up to this point in a how-to like fashion :)

~Cheers

humarf writes

Unfortunately I had no time to write it down, yet. But I got it working as expected in songcast mode even with autoconnect of the bluetooth device. In direct mode it sometimes works sometimes not. But I have not given up - just had no time.

I am confident that this weekend I find some time to write down how I got it working.

Best humarf

PhyberApex writes

That would be awesome. Looking forward to this!

~Cheers

humarf writes

# upmpdcli bluetooth support howto

## assumptions

This howto describes integration of a bluetooth audio source into upmpdcli audio system. It assumes that upmpdcli and sc2mpd packages are already installed and configured.

## install software

First install bluetooth related software. Required packages are:

  • bluez

  • bluez-libs

  • bluez-firmware

  • bluez-utils

bluez release has to be >= 5.0.

Depending on your distro package names might differ. To make your computer operate as bluetooth audio sink you also need to install bluez-alsa. This package can be found on here on git https://github.com/Arkq/bluez-alsa. For arch linux there is a package in AUR called bluez-alsa-git that does the job.

## setup bluetooth

Assuming that your bluetooth dongle is supported and setup you just have to start bluetooth service - systemctl start bluetooth.

If you are on a raspberry pi for me it was necessary to set bluetooth service to a higher priority otherwise I got glitches in audio playback. Following file needs to be created:

/etc/systemd/system/bluetooth.service.d/10-bluealsa.conf

[Service]
CPUSchedulingPolicy=rr
CPUSchedulingPriority=50
Slice=-.slice

Make sure bluetooth serve is loaded at atartup by typing systemctl enable bluetooth.

On a raspberry pi3 integrated bluetooth device is also working.

Now you can start bluealsa service: systemctl start bluealsa. Make it automatically starting at boot time: systemctl enable bluealsa

Attention: Sometimes this makes problems because bluealsa starts after bluez but bluez was not fully setup yet. Did not find a better solution that to restart bluealsa manually. Since my raspberry pi is always on it’s no problem for me. If someone knows how to make systemd wait that a service is fully setup please let me know.

## setup bluetooth devices

Now setup your bluetooth devices. A good tool for that is bluetoothctl. Search, pair and trust your devices. In case of problems please refer to https://wiki.archlinux.org/index.php/bluetooth#bluetoothctl.

## test setup

Now that you have your audio source connected test if it’s working: bluealsa-aplay XX:XX:XX:XX:XX:XX

## setup bluetooth input

Finally a new input source for upmpdcli needs to be setup. Sample scripts are available in /usr/share/upmpdcli. Copy script Analog-Input to Bluetooth-Input. Setting a symbolic link is not sufficient because the script needs a little tweek:

Go to line 106 and change device = open(path).read().strip() to device = subprocess.Popen([path, ""], stdout=subprocess.PIPE).communicate()[0] Go to line 121 and change sender_name = "%s UxSender" % upmpdcli_fname to sender_name = "%s Bluetooth" % upmpdcli_fname Go to line 159 and change '-f', 'cd', '-t', 'raw', '-'), to '-f', 'dat', '-t', 'raw', '-'), Go to line 169 and change "-A", "44100:16:2:1", to "-A", "48000:16:2:1",

At the end of this little howto a patched input file is attached.

# Explanation: First change reads input source from device file - but to be able to make an autoselection file needs to be executable. It returns required device string. Second change is for convinience only. It makes bluetooth sender easier to find in your network. Third and fourth change set up a different sampling rate. For whatever reasons it did not get it working using 44,1kHz.

Change to directory /usr/share/upmpdcli/src_scripts and create a symbolic link to Bluetooth-Input file named Digital-Bluetooth.

Create a file postscript-Bluetooth with following content:

#!/bin/bash
mac=`hcitool con|awk '/..:..:..:..:..:../ {print $3; exit}'`
if [[ ${mac} != '' ]]; then
        echo -e "disconnect ${mac}\nexit\n" | bluetoothctl  > /dev/null
        sleep 2
fi

Explanation: This code snippet disconnects your device when another input source in upmpdcli is selected.

Last step is to create a file called device-Bluetooth with following content:

#!/bin/bash
default="XX:XX:XX:XX:XX:XX"
mac=`hcitool con|awk '/..:..:..:..:..:../ {print $3; exit}'`
if [[ ${mac} == '' ]]; then
        #echo "no device connected, connecting to ${default} ..."
        echo -e "connect ${default}\nexit\n" | bluetoothctl  > /dev/null
        sleep 5
        mac=`hcitool con|awk '/..:..:..:..:..:../ {print $3; exit}'`
        printf "bluealsa:HCI=hci0,DEV=${mac},PROFILE=a2dp"
else
        printf "bluealsa:HCI=hci0,DEV=${mac},PROFILE=a2dp"
fi

Explanation: default should be the mac-adress of your favorite bluetooth device. If no other device is connected it tries to establish a connection to this device. If a different device is already connected it uses this one.

Mind that Bluetooth-Input, device-Bluetooth and postscript-Bluetooth need to be executable.

After restarting upmpdcli a new input called Bluetooth come should come up that plays from your device. If you have more than one openhome device in your network that supports songcast receiver you can perfectly share playback with that device.

## possible improvements

  • create a script that does not use songcast functionality to get this usable for video playback also. With songcast video and audio are not in sync

  • once bluetooth device is connected it can be controlled via dbus. Metadata can also be fetched via dbus. Theoretically it should be possible to fully control bluetooth audio source from upmpdcli using a control point.

Attached is a copy of the patched Input script. [Bluetooth-Input.txt](https://github.com/medoc92/upmpdcli/files/908202/Bluetooth-Input.txt)

PhyberApex writes

Awesome thanks!

medoc92 writes

Hi,

This is nice, and I will link to it from the upmpdcli manual, it’s an excellent example of creating a non-trivial external source. Thanks !

medoc92 writes

Closing the issue, because there does not seem to be a problem. The main article is directly linked from the upmpdcli manual so it should be easy enough to find, thanks for writing it !

I should probably start a tips and tricks section somewhere to help people find out about what they can do.