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.


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


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