Mopidy output to bluetooth speakers and audio out

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

Ciao Fabio,

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

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.

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

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

1 Like

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 ...

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?

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

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?

1 Like

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).

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.

IT IS WORKING!

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

Thanks!

on a pi3, i read al post. Your config works for me. Thanks a lot

1 Like

Hello, I was wondering if it would be too crazy to this same thing but with two bluetooth speakers? This could save me some nasty wiring and saving the expense of an entire rpi for each speaker on my house.

You are great! The solution is also working for me with only a small issue I would like to resolve and I hope you can help me. The jack output and BT are working together as you described above but if I turn off my BT device the other output also falls silent with error in the log:

ERROR GStreamer error: gst-resource-error-quark: Error outputting to audio device. The device has been disconnected. (
ERROR GStreamer error: gst-resource-error-quark: Could not open audio device for playback. (6)

Is there a possible configuration to keep jack output working when the system does not find the BT device?

I got the same too… Don’t know how to fix, also because I have switched to an external bluetooth as I was in the need of more range.

Managed to get working on RPI4 using the configuration above! Thank you so much.

Hi, @fmarzocca I tried to follow the instructions but I am not able to make it work properly.
I have a Mopidy as a service, latest version in rpi. my audio works (with the jack) when I set output = alsasink instead of the default autoaudiosink. My bluetooth is paired and it works when used with youtube.

my .asoundrc looks like this

pcm.!default {
type asym
playback.pcm {
type plug
slave.pcm “output”
}
capture.pcm {
type plug
slave.pcm “input”
}
}

pcm.output {
type bluealsa
device “B9:12:32:79:B0:A2”
profile “a2dp”
}

however that does not work when testing separately
aplay -D output /usr/share/sounds/alsa/Noise.wav
Playing WAVE ‘/usr/share/sounds/alsa/Noise.wav’ : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
aplay: set_params:1345: Channels count non available

ctl.!default {
type bluealsa
}

and I can’t make gst-launch-1.0 to play bluetooth following your command.

however I do get the test tone in bluetooth by testing with
gst-launch-1.0 audiotestsrc ! audioconvert ! audioresample ! alsasink

any help you can give me is appreciated…
thanks

actually I got bluetooth working by setting output = alsasink device = output and copying .asoundrc to /etc/asound.conf

I want to output my audio to 2 alsa devices silmutaneously as well, but no bluetooth involved.

1st output to my raspberry’s headphone jack (device=plug:output)
2nd output to an additional alsa device named peppyalsa (device=peppyalsa), which is used to feed audio into a named pipe (fifo), on the other end of that pipe/fifo I’m running peppymeter (a vu meter on my SPI touchscreen).
peppyalsa is an alsa plugin created by the maker of peppymeter to work around the blocking behaviour of fifo.

When testing the peppyalsa device with aplay the vu meter (peppymeter) starts immediately:
aplay -D peppyalsa /usr/share/sounds/alsa/Front_Center.wav

Now I try to output my audio from mopidy to my 2 alsa devices.
This works somehow, BUT the output to peppyalsa starts exactly after 1:05 minutes, so my vu meter starts too late, once it’s running audio is in sync.

Here are 2 output configuration I tried that work like this:

output = audioresample ! tee name=t ! queue ! alsasink device=plug:output t. ! queue ! audioresample ! alsasink device=peppyalsa

output = tee name=t t. ! queue ! alsasink device=plug:output t. ! queue ! alsasink device=peppyalsa

Both have the same behaviour, I tried some other gstreamer configs but these didn’t work at all.
I don’t know where this start delay is coming from.

Can anybody point me in the right direction how to get audio output on both alsa devices silmutaneously ?

I hope someone gets the idea.

See here too: Output to 2 alsa devices silmutaneously?