Skip to content
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

Look into adding a gstreamer fifo sink #775

Closed
adamcik opened this issue Jul 8, 2014 · 73 comments
Closed

Look into adding a gstreamer fifo sink #775

adamcik opened this issue Jul 8, 2014 · 73 comments
Labels
A-audio Area: Audio layer C-enhancement Category: A PR with an enhancement or an issue with an enhancement proposal

Comments

@adamcik
Copy link
Member

adamcik commented Jul 8, 2014

This keeps coming up as people really seem to like ncmpcpp's visualizer

Trick for making a reliable FIFO sink is twofold. You need to use non-blocking writes, which means opening the write socket will fail unless there is a reader, hence you need a reader as well. Secondly if the buffer fills up because the external reader falls behind or there is none, your internal reader needs to clear the buffer.

Following code captures the basic gist of this, but still needs some more work with respect to error handling.

import errno
import os
import stat

LINUX_FIFO_BUFFER_SIZE = 65536


class FifoStreamer(object):                                                     
    def __init__(self, location):                                               
        self.location = location                                                
        self.reader = None                                                      
        self.writer = None                                                      

    def create(self):                                                           
        try:                                                                    
            mode = os.stat(self.location).st_mode                               
            if not stat.S_ISFIFO(mode):                                         
                raise Exception('File exists but is not a FIFO')                
        except OSError as e:                                                    
            if e.errno == errno.ENOENT:                                         
                os.mkfifo(self.location)                                        
            else:                                                               
                raise                                                           

        # TODO: wrap in could not open reader / writer?
        self.reader = os.open(self.location, os.O_NONBLOCK | os.O_RDONLY)       
        self.writer = os.open(self.location, os.O_NONBLOCK | os.O_WRONLY)       

    def close(self):                                                            
        # TODO: make closing robust
        os.close(self.writer)                                                   
        os.close(self.reader)                                                   

    def write(self, data):                                                      
        while data:                                                             
            try:                                                                
                written = os.write(self.writer, data)                           
                data = data[written:]                                           
            except OSError as e:                                                
                if e.errno == errno.EINTR:                                      
                    continue                                                    
                elif e.errno in (errno.EAGAIN, errno.EWOULDBLOCK):              
                    self.flush()                                                
                else:                                                           
                    raise                                                       

    def flush(self):                                                            
        while True:                                                             
            try:                                                                    
                if not os.read(self.reader, LINUX_FIFO_BUFFER_SIZE):                             
                    break                                                       
            except OSError as e:                                                
                if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK):                
                    break                                                       
                elif e.errno == errno.EINTR:                                    
                    continue                                                    
                else:                                                           
                    raise 

The code above now needs to be integrated with GStreamer do actually do it's thing. Assuming 0.10 this is actually very much doable, reason I am hesitant is that we are planing a move to 1.x and the gir binding are not suited for making elements in python. In the case of this code in 1.x the problem boils down to not being able to create the pad templates that BaseSink expect to find. Creating this as a plain element might be doable, but you would need to re-implement way to much of the handling BaseSink makes sure you get right.

import gobject                                                                  

import pygst                                                                    
pygst.require('0.10')                                                           
import gst                                                             


class FifoSink(gst.BaseSink):                                                   
    __gstdetails__ = (                                                          
        'FifoSink',                                                             
        'Sink',                                                                 
        'Sink designed to handle FIFO output.',                        
        'Mopidy')                                                               

    __gsttemplates__ = (gst.PadTemplate('sink', gst.PAD_SINK, gst.PAD_ALWAYS,   
                                        gst.caps_new_any()),)                   

    # TODO: don't allow changing location in flight, i.e. create getter/setter
    location = gobject.property(type=str)                                       

    def __init__(self):                                                         
        gst.BaseSink.__init__(self)                                             
        self.streamer = None                                                    

    def do_start(self):                                                                                               
        self.streamer = FifoStreamer(self.location)                             
        self.streamer.create()                                                  
        return True                                                             

    def do_stop(self):                                                          
        self.streamer.close()                                                   
        return True                                                             

    def do_render(self, buf):                                                   
        try:                                                                    
            self.streamer.write(bytes(buf))                                     
            return gst.FLOW_OK                                                  
        except OSError as e:                                                    
            self.error("Failed: %s", e)                                         
            return gst.FLOW_ERROR                                               


gobject.type_register(FifoSink)                                                 
gst.element_register(                                                           
    FifoSink, 'fifosink', gst.RANK_MARGINAL)                                    

if __name__ == '__main__':                                                      
    import gobject                                                              
    gobject.threads_init()                                                      

    output = """                                                                
capsfilter caps="audio/x-raw-int,width=16,rate=44100,channels=1" ! 
tee name=t 
t. ! queue ! alsasink                                                           
t. ! queue ! fifosink location=/tmp/test2.fifo                                  
"""                                                                             

    sink = gst.parse_bin_from_description(                                      
        output, ghost_unconnected_pads=True)                                    

    playbin = gst.element_factory_make('playbin2')                              
    playbin.set_property('audio_sink', sink) 

Note that one problem I ran into testing this was actually forgetting to match the audio format expected by ncmpcpp, so make sure mono/stereo do indeed match up.

@CestDiego
Copy link

Where did this go? will this be added to the main package?

@adamcik
Copy link
Member Author

adamcik commented Oct 11, 2014

This isn't being worked on as we would need to convert it to GStreamer 1.0, and all my experiments with that so far have uncovered problems when doing custom elements in python. There are other ways of maybe solving it all, but not something I have time to work on.

@johnhamelink
Copy link

I'd like to see FIFO support added :)

@bartenbach
Copy link

I just found this searching for a way to get ncmpcpp's music visualizer to work with mopidy. I am in favor.

@CestDiego
Copy link

Yes, that's the same reason why I found this. It would be really great to
be able to visualize streamed music,

2014-11-06 2:19 GMT-05:00 Blake notifications@github.com:

I just found this searching for a way to get ncmpcpp's music visualizer to
work with mopidy. I am in favor.


Reply to this email directly or view it on GitHub
#775 (comment).

@kingosticks
Copy link
Member

There are gstreamer visualisation plugins, can you not just use those?
On 6 Nov 2014 08:35, "Diego Berrocal" notifications@github.com wrote:

Yes, that's the same reason why I found this. It would be really great to
be able to visualize streamed music,

2014-11-06 2:19 GMT-05:00 Blake notifications@github.com:

I just found this searching for a way to get ncmpcpp's music visualizer
to
work with mopidy. I am in favor.


Reply to this email directly or view it on GitHub
#775 (comment).


Reply to this email directly or view it on GitHub
#775 (comment).

@adamcik
Copy link
Member Author

adamcik commented Nov 6, 2014

Note that those are on their way out in the next release.

@andreasboden
Copy link

Is there someone working on this? Would be really nice to be able to use the ncmpcpp visualizer with mopidy.

@adamcik
Copy link
Member Author

adamcik commented Feb 13, 2015

Not that I know of, and we likely don't want to do this as GStreamer element as it would block our migration to GStreamer 1.x.

@adamcik
Copy link
Member Author

adamcik commented Feb 25, 2015

This is IMO also blocked on adding back proper support for outputs.

@codeurge
Copy link

codeurge commented Apr 15, 2015

Just adding that I also came across this issue when trying to add visualizer support to Mopidy/ncmpcpp. Would love to have this in the future even if it's not being worked on currently. I'd also like to extend my utmost respect for those who contribute their time to open source projects. 😄

@wernight
Copy link

Ideally this would work remotely. Mopidy's power lies really in being a solution that can be in your private cloud.

@liamw9534
Copy link

In general, FIFOs are not a very portable method of interprocess communications and should be avoided IMO. They also have some nasty side-effects, already mentioned in this thread. I think you are better off dumping your packets out using a UDP sink personally....that's a more generic solution and can easily be adapted to something that writes to a FIFO (if necessary) outside of Mopidy....it's a single line of shell script to read data from a UDP port (using netcat) and write it to a FIFO.

@wernight
Copy link

That sounds good. May be clients lie ncmpcpp would also allow using that as input.

Another idea is to use PulseAudio directly as it would require no extra implementation on Mopidy's side. The Docker container I made uses TCP to access PulseAudio over network. ncmpcpp could actually use that directly.

@liamw9534
Copy link

From what I've read, the visualizer is just running an FFT on blocks of samples which are read from a FIFO file. The point I am making is that you can create a FIFO outside of Mopidy using mkfifo and then read the UDP data from Mopidy using netcat and redirect the output from netcat to the FIFO file. Thus nothing needs to change as far as ncmpcpp is concerned, it just reads the FIFO file.

To achieve what you're aiming on Mopidy requires no implementation effort since you can change the audio output property to output to a udpsink GStreamer element. More likely you would want to arrange it as part of a "tee" which outputs to both your ALSA/Pulse sink and the udpsink.

@liamw9534
Copy link

The following should work....not tested so might need some tweeking.

In Mopidy audio configuration:

output = tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink port=5555

On your Linux host, launch netcat to listen on localhost for UDP data on port 5555 and output the samples to the FIFO:

mkfifo /tmp/mopidy.fifo
nc -u -l 127.0.0.1 5555 > /tmp/mopidy.fifo &

In your mpd.conf:

audio_output {
    type                    "fifo"
    name                    "my_fifo"
    path                    "/tmp/mopidy.fifo"
    format                  "44100:16:2"
}

@liamw9534
Copy link

Note: If you are using a PulseAudio output, it might be possible to do something similar with its TCP direction connection module. However, you might need to reverse engineer any protocol it runs over the top of the TCP connection e.g., it might not be possible to treat it as a raw sink.

@wernight
Copy link

Thank @liamw9534 for sharing. It would have taken me a while to understand the config enough to do that or even know I could. I'll try to add that to the Docker container see if it works.

@adamcik
Copy link
Member Author

adamcik commented Apr 28, 2015

This might run into issues if you don't have something emptying the fifo though. As netcat will fill the kernel buffer and then fail. And depending on how the FIFO is opened you might also run into issues as FIFOs can require a reader to be present to be writable :/

@adamcik
Copy link
Member Author

adamcik commented Apr 28, 2015

But you could adapt my FifoStreamer code to accept the UDP data and handle this for you as I hopefully already have handled most of the error cases you can run into there.

@wernight
Copy link

@adamcik If you have a working script I'd be glad to include it as part of docker-ncmpcpp for people to use. I'd also change docker-mopidy to broadcast on UDP by default using the output trick above.

@liamw9534
Copy link

I did some basic experiments on the command-line and it all works fine provided you use a connection timeout e.g., nc -kluw 1 127.0.0.1 5555 > /tmp/mopidy.fifo. This forces netcat to always listen for a new source port connection after the last connection drops (1s timeout).

The above command works irrespective of whether or not anything is reading from the FIFO file and also works if the process reading from the FIFO file stops and closes the file.

@adamcik
Copy link
Member Author

adamcik commented Apr 29, 2015

@wernight see the description of this bug, that is all the code I have.

@liamw9534
Copy link

And just for belts and braces, I would stick the command in a while loop e.g., while :; do nc -kluw 1 127.0.0.1 5555> /tmp/mopidy.fifo; sleep 1; done - if it does exit, it will just launch again after 1 second delay.

@lrvick
Copy link

lrvick commented May 2, 2015

@liamw9534 You have a mpd.conf there. I am confused by this. You are running a standalone MPD server in addition to mopidy-mpd?

@liamw9534
Copy link

@lrvick yes my mistake, was of course thinking about config that needs to be added to ~/.ncmpcpp/config

@wernight
Copy link

wernight commented May 8, 2015

.config/mopidy/mopidy.conf

...

[audio]
output = tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink port=5555
$ mkfifo /tmp/mopidy.fifo
$ while :; do nc -kluw 1 127.0.0.1 -p 5555> /tmp/mopidy.fifo; sleep 1; done

(added -p here).

~/.ncmpcpp/config

audio_output {
    type                    "fifo"
    name                    "my_fifo"
    path                    "/tmp/mopidy.fifo"
    format                  "44100:16:2"
}

(done also in wernight/docker-mopidy and wernight/docker-ncmpcpp)

However it seems it cannot connect to 5555 even though the log of Mopidy shows it understood the output config. netstat shows also no open UDP on 5555. I don't fully understand the output line: tee is a bash command, the rest looks like Mopidy stuff.

I did however find udp6 [::]:51307 while playing music.

@kingosticks
Copy link
Member

My comment was based off the ncmpcpp source.

Mopidy's Mute output is disabled by default i.e. the audio is not muted. The ncmpcpp visualiser will take the output you gave it, disable it (no effect) and then enable it, thus muting the audio. Arguably they should just toggle it twice.

The audio being in the wrong format is a good possibility. You have nothing in your gstreamer pipeline to ensure it is correct unlike @adamcik had in his code above.

@liamw9534
Copy link

Hard to see how the format could be a problem....it's 16-bit signed
integers. The worst that could happen is that you swap the L/R channels?

On 13 May 2015 at 16:33, Nick Steel notifications@github.com wrote:

My comment was based off the ncmpcpp source
http://git.musicpd.org/cgit/mirror/ncmpcpp.git/tree/src/visualizer.cpp.

Mopidy's Mute output is disabled by default i.e. the audio is not muted.
The ncmpcpp visualiser will take the output you gave it, disable it (no
effect) and then enable it, thus muting the audio. Arguably they should
just toggle it twice.

The audio being in the wrong format is a good possibility. You have
nothing in your gstreamer pipeline to ensure it is correct unlike @adamcik
https://github.com/adamcik had in his code above.


Reply to this email directly or view it on GitHub
#775 (comment).

@liamw9534
Copy link

And even if the byte ordering was wrong, you might then just expect the FFT
output to generate the wrong frequency response......but you'd still see
something.

On 13 May 2015 at 16:37, Liam Wickins liamw9534@gmail.com wrote:

Hard to see how the format could be a problem....it's 16-bit signed
integers. The worst that could happen is that you swap the L/R channels?

On 13 May 2015 at 16:33, Nick Steel notifications@github.com wrote:

My comment was based off the ncmpcpp source
http://git.musicpd.org/cgit/mirror/ncmpcpp.git/tree/src/visualizer.cpp.

Mopidy's Mute output is disabled by default i.e. the audio is not muted.
The ncmpcpp visualiser will take the output you gave it, disable it (no
effect) and then enable it, thus muting the audio. Arguably they should
just toggle it twice.

The audio being in the wrong format is a good possibility. You have
nothing in your gstreamer pipeline to ensure it is correct unlike
@adamcik https://github.com/adamcik had in his code above.


Reply to this email directly or view it on GitHub
#775 (comment).

@kingosticks
Copy link
Member

yeh true, so maybe it's because leaving Mopidy's Mute output enabled means the udpsink won't send any data.

@wernight
Copy link

cat /tmp/mdp.fifo (created from UDP as above) correctly shows constant stream of data.

I looked at visualizer ncmpcpp code:

  1. opens the file as O_RDONLY | O_NONBLOCK
  2. reads from top; given it's set for stereo in my mopidy config, it should be 44100:16:2.

Anyone can also try from my branch (after having installed Docker):

git clone https://github.com/wernight/docker-mopidy.git
cd docker-mopidy
git checkout udpsink
docker build -t mopidy .
cd ..

git clone https://github.com/wernight/docker-ncmpcpp.git
cd docker-ncmpcpp
git checkout udpsink
docker build -t ncmpcpp .
cd ..

# Remember to enable PulseAudio over network 

docker run --name mopidy -d \
      -e PULSE_SERVER=tcp:$(hostname -i):4713 \
      -e PULSE_COOKIE_DATA=$(pax11publish -d | grep --color=never -Po '(?<=^Cookie: ).*') \
      mopidy
docker run --rm -it --link mopidy:mopidy ncmpcpp --host mopidy

@s-ol
Copy link

s-ol commented Dec 28, 2015

Had to spend quite some time wrangling netcat as -k didn't work for me, but here is what I came up with to autorestart it on song switches:

while :; do yes $'\n' | nc -lu 127.0.0.1 5555 > /tmp/mopidy.fifo; done

other options as above basically.

@SjRNMzU
Copy link

SjRNMzU commented Feb 6, 2016

@S0lll0s @wernight netcat -k also didn't work for me and had to be restarted after song changes. While your solution works, I've found socat to work better:

while :; do socat -d -d -T 1 -u UDP4-LISTEN:5555 OPEN:/tmp/mopidy.fifo; done

@johnhamelink
Copy link

For arch linux users:

To get nc with -k support you need to install the openbsd-netcat package, but it didn't work for me either, so try using @SjRNMzU 's script - you need the socat package to run it.

@tmb
Copy link

tmb commented Jun 4, 2017

@johnhamelink (I presume you are running Arch from your comment) Have you had issues with the visualizer trying to "catch up" after you pause a song using the socat solution?

@johnhamelink
Copy link

@theos-space I can't say I've noticed that myself

@ranisalt
Copy link

ranisalt commented Jun 6, 2017

I'm on Arch and couldn't get it to work with either nc (both gnu and openbsd) or socat. Additionally, I can't read from gst-launch-1.0 ... udpsink port=5555 with nc -kluw 1 127.0.0.1 5555, as it prints nothing to the screen.

@laur89
Copy link

laur89 commented Aug 27, 2017

Can confirm this works on debian buster (4.11.6-1), mopidy 2.1.0-1, gstreamer1.0-tools 1.12.2-1, ncmpcpp 0.7.4-1+b3, socat 1.7.3.2-1:

start socat in the system startup:

open_mpd_fifo() {
    local fifo
    readonly fifo='/tmp/mpd.fifo'

    mkfifo "$fifo"
    while :; do socat -d -d -T 1 -u UDP4-LISTEN:5555 OPEN:"$fifo"; done
}

mopidy [audio] conf (note host had to be defined for udpsink):

[audio]
output = tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink host=127.0.0.1 port=5555

@r1ft4469
Copy link

ranisalt for Arch you have to compile ncmpcpp with fifo support check here: https://bbs.archlinux.org/viewtopic.php?id=99915

@mosbasik
Copy link

Here's my working Arch setup, after reading the rest of the thread + docs + manpages + assorted blogs. I'm running Mopidy as a system service and sending the audio to the user service PulseAudio via TCP. I've included some additional annotations that will hopefully help the less experienced.

Packages

All of these are from the official Arch repos:

gstreamer 1.12.3-1
mopidy 2.1.0
ncmpcpp 0.8.1  # this had fifo support without any special compiling for me
openbsd-netcat 1.178_3-1  # gnu-netcat lacks the -k flag, as discussed above
pulseaudio 11.1

Setup

Enable mopidy system service:

sudo systemctl enable mopidy.service

Replace mopidy's system config with a symlink to the user config for ease of editing (optional):

sudo ln -sf ~/.config/mopidy/mopidy.conf /etc/mopidy/mopidy.conf

Create the fifo file:

mkfifo "/tmp/mpd.fifo"

Configs

in ~/.config/mopidy/mopidy.conf (or /etc/mopidy/mopidy.conf if you didn't create the symlink): Tell mopidy to send audio to a pulseaudio server listening on localhost and to a UDP sink at localhost:5555

[audio]
output = tee name=t ! queue ! pulsesink server=127.0.0.1 t. ! queue ! udpsink host=127.0.0.1 port=5555

in ~/.ncmpcpp/config: Tell ncmpcpp where to find the fifo file it needs to listen to, and some other miscellaneous settings

visualizer_fifo_path = "/tmp/mpd.fifo"
visualizer_output_name = "my_fifo"
visualizer_sync_interval = "30"
visualizer_in_stereo = "yes"
visualizer_type = "spectrum"
visualizer_look = "+|"

in ~/.config/pulse/default.pa: Tell pulseaudio to accept audio over TCP from localhost (the setting is likely already there and can just be uncommented)

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1

in ~/.zshrc (should also work in ~/.bashrc): Create a wrapper function "nplayer" to handle starting and stopping netcat with ncmpcpp:

nplayer () (nc -kluw 1 127.0.0.1 5555 > /tmp/mpd.fifo & trap "kill $!" EXIT; ncmpcpp)

What this does:

  • define a function with a subshell wrapping its whole contents
  • start a netcat process in the background to listen for the audio data sent to the UDP sink and redirect it to the fifo created earlier. Flags:
    • -k keep listening after current connection is completed
    • -l enable listening mode
    • -u enable UDP mode
    • -w NUM timeout idle connections after NUM seconds (1 sec in this case)
  • set an EXIT trap to kill the netcat process when the ncmpcpp process terminates and causes the function subshell to exit
  • start a ncmpcpp process in the foreground

@ducklin5
Copy link

ducklin5 commented Dec 14, 2018

Im running mopidy on Manjaro (arch distro). I was having trouble with getting any output through socat or netcat. I was able to observer the packets coming in with tcpdump though:
sudo tcpdump -i lo -n udp port 5555 -XX

It took me a long while and I wouldn't have found the issue without @mosbasik .
The issue was not having host=127.0.0.1 after udpsink, why this works for other people and not me, I dont know. But if you're not getting any output it possible this is the case. These 2 worked for me:

[audio]
output = tee name=t ! queue ! autoaudiosink server=127.0.0.1 t. ! queue ! udpsink host=127.0.0.1 port=5555↪

or

[audio]
output = tee name=t ! queue ! autoaudiosink  t. ! queue ! udpsink host=127.0.0.1 port=5555↪

On a side note: I wasn't able to get pulsesink to work so I had to leave it at autoaudiosink, which is what I had it set too before. However the visualizer seems to be really really slow for some reason, Im not sure if that is because of autoaudiosink Works Perfect after a Reboot .. still slightly slow though. With pulselink it kept complaining about gstreamer plugins. Even after (I assume) I installed every plugin package for gst on the official Arch repos. Note flump3dec and mad

Output of `mopidy deps`
Executable: /usr/bin/mopidy
Platform: Linux-4.16.7-1-MANJARO-x86_64-with-glibc2.2.5
Python: CPython 2.7.15 from /usr/lib/python2.7
Mopidy: 2.2.1 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
  requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
    chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
    idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
    urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
  setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
  tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
    futures: 3.2.0 from /usr/lib/python2.7/site-packages
    singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
      six: 1.11.0 from /usr/lib/python2.7/site-packages
    backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
Mopidy-Iris: 3.4.9 from /usr/lib/python2.7/site-packages
  setuptools>=3.3: 40.5.0 from /usr/lib/python2.7/site-packages
  pylast>=1.6.0: 2.3.0 from /usr/lib/python2.7/site-packages
    six: 1.11.0 from /usr/lib/python2.7/site-packages
  Mopidy>=2.0: 2.2.1 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
    tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
      futures: 3.2.0 from /usr/lib/python2.7/site-packages
      singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
        six: 1.11.0 from /usr/lib/python2.7/site-packages
      backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
  Mopidy-Local-Images>=1.0: 1.0.0 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
    Mopidy>=1.1: 2.2.1 from /usr/lib/python2.7/site-packages
      Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
      requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
        chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
        idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
        urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
      setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
      tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
        futures: 3.2.0 from /usr/lib/python2.7/site-packages
        singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
          six: 1.11.0 from /usr/lib/python2.7/site-packages
        backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    uritools>=1.0: 1.0.1 from /usr/lib/python2.7/site-packages
      ipaddress>=1.0.6: 1.0.22 from /usr/lib/python2.7/site-packages
      ipaddress>=1.0.6: 1.0.22 from /usr/lib/python2.7/site-packages
  ConfigObj>=5.0.6: 5.0.6 from /usr/lib/python2.7/site-packages
  raven>=6.1.0: 6.9.0 from /usr/lib/python2.7/site-packages
    contextlib2: 0.5.5 from /usr/lib/python2.7/site-packages
Mopidy-Local-Images: 1.0.0 from /usr/lib/python2.7/site-packages
  setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
  Mopidy>=1.1: 2.2.1 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
    tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
      futures: 3.2.0 from /usr/lib/python2.7/site-packages
      singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
        six: 1.11.0 from /usr/lib/python2.7/site-packages
      backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
  uritools>=1.0: 1.0.1 from /usr/lib/python2.7/site-packages
    ipaddress>=1.0.6: 1.0.22 from /usr/lib/python2.7/site-packages
    ipaddress>=1.0.6: 1.0.22 from /usr/lib/python2.7/site-packages
Mopidy-Spotify-Tunigo: 1.0.0 from /usr/lib/python2.7/site-packages
  Mopidy>=0.19.0: 2.2.1 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
    tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
      futures: 3.2.0 from /usr/lib/python2.7/site-packages
      singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
        six: 1.11.0 from /usr/lib/python2.7/site-packages
      backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
  Mopidy-Spotify>=1.2.0: 3.1.0 from /usr/lib/python2.7/site-packages
    Mopidy>=2.0: 2.2.1 from /usr/lib/python2.7/site-packages
      Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
      requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
        chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
        idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
        urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
      setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
      tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
        futures: 3.2.0 from /usr/lib/python2.7/site-packages
        singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
          six: 1.11.0 from /usr/lib/python2.7/site-packages
        backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    pyspotify>=2.0.5: 2.0.5 from /usr/lib/python2.7/site-packages
      cffi>=1.0.0: 1.11.5 from /usr/lib/python2.7/site-packages
        pycparser: 2.19 from /usr/lib/python2.7/site-packages
    requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
  setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
  tunigo>=1.0.0: 1.0.0 from /usr/lib/python2.7/site-packages
    requests>=2.0.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
Mopidy-SoundCloud: 2.1.0 from /usr/lib/python2.7/site-packages
  setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
  Mopidy>=1.0: 2.2.1 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
    tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
      futures: 3.2.0 from /usr/lib/python2.7/site-packages
      singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
        six: 1.11.0 from /usr/lib/python2.7/site-packages
      backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
  requests>=2.0.0: 2.20.1 from /usr/lib/python2.7/site-packages
    chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
    idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
    urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
Mopidy-Spotify: 3.1.0 from /usr/lib/python2.7/site-packages
  Mopidy>=2.0: 2.2.1 from /usr/lib/python2.7/site-packages
    Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
    requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
      chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
      idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
      urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
    setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
    tornado>=4.4: 5.1.1 from /usr/lib/python2.7/site-packages
      futures: 3.2.0 from /usr/lib/python2.7/site-packages
      singledispatch: 3.4.0.3 from /usr/lib/python2.7/site-packages
        six: 1.11.0 from /usr/lib/python2.7/site-packages
      backports_abc>=0.4: 0.5 from /usr/lib/python2.7/site-packages
  Pykka>=1.1: 1.2.1 from /usr/lib/python2.7/site-packages
  pyspotify>=2.0.5: 2.0.5 from /usr/lib/python2.7/site-packages
    cffi>=1.0.0: 1.11.5 from /usr/lib/python2.7/site-packages
      pycparser: 2.19 from /usr/lib/python2.7/site-packages
  requests>=2.0: 2.20.1 from /usr/lib/python2.7/site-packages
    chardet>=3.0.2: 3.0.4 from /usr/lib/python2.7/site-packages
    idna>=2.5: 2.7 from /usr/lib/python2.7/site-packages
    urllib3>=1.21.1: 1.24.1 from /usr/lib/python2.7/site-packages
  setuptools: 40.5.0 from /usr/lib/python2.7/site-packages
GStreamer: 1.14.4.0 from /usr/lib/python2.7/site-packages/gi
  Detailed information: 
    Python wrapper: python-gi 3.30.2
    Relevant elements:
      Found:
        uridecodebin
        souphttpsrc
        appsrc
        alsasink
        osssink
        oss4sink
        pulsesink
        id3demux
        id3v2mux
        lamemp3enc
        mpegaudioparse
        mpg123audiodec
        vorbisdec
        vorbisenc
        vorbisparse
        oggdemux
        oggmux
        oggparse
        flacdec
        flacparse
        shout2send
      Not found:
        flump3dec
        mad

@ghost
Copy link

ghost commented Mar 1, 2019

I'm running into an issue trying to get udpsink working with Mopidy and all remote ncmpcpp clients. Mopidy is setup with MacVLAN in a docker environment. I can successfully see the port on the container.

nc -vz -u mopidy.lan 5555
found 0 associations
found 1 connections:
     1:	flags=82<CONNECTED,PREFERRED>
	outif (null)
	src x.x.x.x port 50630
	dst x.x.x.x port 5555
	rank info not available

Connection to mopidy.lan port 5555 [udp/personal-agent] succeeded!

Currently Mopidy is using the following bit of config:

[audio]
mixer = software
mixer_volume = 100
output = tee name=t ! queue ! lamemp3enc ! shout2send async=false mount=mopidy ip="mopidy.lan" port=8092 username="some username" password="some password" t. ! queue ! udpsink host=0.0.0.0 port=5555

Any thoughts to how I can use netcat to successfully get the raw data into mpd.fifo? Using the following doesn't work, I think because I'm using netcat in the wrong way. Some research hasn't provided any answers, so hopefully someone can point me in the right direction.

#!/bin/bash

mkfifo /tmp/mpd.fifo
while :; do yes $'\n' | nc -lu mopidy 5555 > /tmp/mpd.fifo; done

I get the following error:

nc: Can't assign requested address

Any thoughts on how I can get this to work?

Cheers!

@arybczak
Copy link
Contributor

arybczak commented Dec 17, 2020

FYI I added support for gstreamer's udpsink to ncmpcpp so now it can be used directly without fifo hacks.

See ncmpcpp/ncmpcpp@fb886f6 for more details.

Below a teaser. This is mopidy + mopidy-spotify + mopidy-mpd + ncmpcpp.

simplescreenrecorder-2020-12-17_23.07.55.mp4

@jodal
Copy link
Member

jodal commented Dec 18, 2020

@arybczak Awesome! You should post this to https://discourse.mopidy.com/c/show-and-tell/9

@pspeder
Copy link

pspeder commented Feb 12, 2021

@adamcik Doesn't this mean that this nearly 7-yo issue is "deprecated" in favour of a better resolution to the real-world issue that sparked it (supporting visualisations in ncmpcpp)?

@kingosticks
Copy link
Member

@pspeder, what exactly do you mean? Is there a problem with using #775 (comment) ?

@pspeder
Copy link

pspeder commented Feb 13, 2021

@kingosticks Was simply suggesting that this issue be closed 🙂

@kingosticks
Copy link
Member

I do agree with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-audio Area: Audio layer C-enhancement Category: A PR with an enhancement or an issue with an enhancement proposal
Projects
None yet
Development

No branches or pull requests