Mopidy output to bluetooth speakers and audio out

#1

Hi,

I am running latest Mopidy version (as a service) and it is perfectly working connected to my HiFi amplifier through Raspi audio output.

I am wondering if it’s possible to add also bluetooth streaming to a remote speaker, using internal Raspi bluetooth services, without disabling audio out to amplifier (both working).

#2

On Raspbian you can select a bluetooth speaker as a default sink with an /etc/asound.conf configuration that looks like this (leveraging bluealsa, no pulse needed):

pcm.!default {
    type asym
    capture.pcm "mic"
    playback.pcm "speaker"
}

pcm.mic {
    type plug
    slave {
        pcm "hw:1,0"
    }
}

pcm.speaker {
    type plug
    slave.pcm {
        type bluealsa
        device "BLUETOOTH_SPEAKER_PHYSICAL_ADDRESS"
        profile "a2dp"
    }
}

Routing the audio to two output devices at the same time might be a bit trickier though. A feature has been worked in the past to support multiple/plug’n’play outputs but as far as I know it’s been abandoned. Probably you can set up a gstreamer pipeline that copies the audio to two sinks, but I’m relatively confident that in the case of a bluetooth and a “standard” sink it might break. The most viable option I’d advise for now would be to leverage Snapcast: your mopidy instance can dump the audio to a snapserver pipe, and you can use two snapclient instances connected to two different sinks via pulseaudio.

1 Like
#3

Ciao Fabio,

thanks for the reply. Shouldn’t PulseAudio be able to stream from one source to multiple pieces of sound hardware?

#4

You can use pulse to route the audio from an app to a specific output. Routing from the same app to multiple devices might be possible (https://askubuntu.com/questions/78174/play-sound-through-two-or-more-outputs-devices) but I’ve never tested it myself, as I personally prefer the mopidy+snapcast option as it gives me much more flexibility.

#5

That abandoned feature was really about dynamic outputs (part of the MPD protocol we do not support). For a static setup where you are happy to always output to both Bluetooth and your soundcard then a custom Gstreamer pipeline similar to what is described in ours docs for Icecast should work. Something like the following lets me output to two soundcards so maybe you can adapt that:

[audio]
output = tee name=t ! queue ! audioresample ! alsasink device=hw:1,0 t. ! queue ! audioresample ! alsasink device=hw:2,0

Where hw:1,0 would be Card 1, device 0 and hw:2,0 is Card 2, device 0 (taken from the output of aplay -l on my system). I’m not sure if your bluetooth device would appear in aplay -l but you should also be able to refer to specific devices by name e.g. alsasink device-name=<something>.

1 Like
#6

I got this error:
2019-03-17 17:03:14,558 ERROR [1937:Audio-2] mopidy.audio.actor: Failed to create audio output "output = tee name=t ! queue ! audioresample ! alsasink device-name=jack t. ! queue ! audioresample ! alsasink device-name=BOSE": gst_parse_error: syntax error (0)

My .asoundrc is:
pcm.!default plug:jack

pcm.!jack {
  type plug
  slave {
  pcm "hw:0,0"
  }
}


pcm.BOSE {
        type plug
        slave.pcm {
                type bluealsa
                device "04:52:C7:50:B5:24"
                profile "a2dp"
        }
}

Testing separately the two devices are working:

Play from bluetooth:
aplay -D BOSE /usr/share/sounds/alsa/Rear_Center.wav

Play from audio jack:
aplay /usr/share/sounds/alsa/Rear_Center.wav

#7

And this is the output from a direct console command:

gst-launch-1.0 filesrc location=/media/CE1B-6D79/Pearl\ Jam/Black.mp3 tee name=t ! queue ! audioresample ! alsasink device-name=jack t. ! queue ! audioresample ! alsasink device-name=BOSE

(gst-launch-1.0:1981): GLib-GObject-WARNING **: g_object_set_property: property 'device-name' of object class 'GstAlsaSink' is not writable

(gst-launch-1.0:1981): GLib-GObject-WARNING **: g_object_set_property: property 'device-name' of object class 'GstAlsaSink' is not writable
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstFileSrc:filesrc0: Internal data stream error.
Additional debug info:
gstbasesrc.c(2950): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesrc0:
streaming stopped, reason not-linked (-1)
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...
RPI3 built-in bluetooth support
#8

The error is quite descriptive, turns out that device-name property is read-only. That’s my mistake. You can see that for yourself at https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-alsasink.html

So you’ve got to use the device property instead. Did that not work?

#9

aplay -l does not show the bluetooth… I don’t know how to address the Bluetooth device

#10

I am progressing on this.

Now I can play BOTH bluetooth and audio jack (with the .asoundrc file posted above), with this pipe:

gst-launch-1.0 uridecodebin uri=file:///media/MUSIC/Pearl\ Jam/Black.mp3 ! audioresample ! tee name=t ! queue ! alsasink device=jack t. ! queue ! audioresample ! alsasink device=BOSE

The trick was to replace “device” with the name assigned in .asoundrc.

But when I tried to change the config option with this:

output = audioresample ! tee name=t ! queue ! alsasink device=jack t. ! queue ! audioresample ! alsasink device=BOSE

playing a track I had this error in log:

2019-03-22 15:22:34,983 ERROR [1263:MainThread] mopidy.audio.gst: GStreamer error: gst-resource-error-quark: Could not open audio device for playback. (6)
2019-03-22 15:22:34,984 WARNING [1263:Audio-2] mopidy.audio.actor: Setting GStreamer state to GST_STATE_PLAYING failed
2019-03-22 15:22:34,987 WARNING [1263:Core-14] mopidy.core.tracklist: Track is not playable: local:track:MUSIC/Astor%20Piazzolla/Oblivion/Baires%20%2772.mp3
2019-03-22 15:23:21,168 INFO [1263:MainThread] mopidy.commands: GLib mainloop got SIGTERM. Exiting..

Any idea?

#11

Running Mopidy as your user or as the service? If the latter, the service runs as user mopidy which will have no idea about anything in your user .asoundrc file. It also may or may not have access to the bluetooth device. If the former, try pairing up those audioresample elements with an audioconvert element (wild guess).

#12

mmmh. you’re right. I am running as a service, that’s why it works if I launch it as my user…I will investigate more.

Anyway, mopidy is not claiming about the device (bluetooth) but about the fact that the track is not playable. It is a different error than before.

#13

IT IS WORKING!

I have just copied .asoundrc to /etc/asound.conf and added mopidy user to bluetooth group!

Thanks!