Mopidy: 考虑添加一个 gstreamer fifo sink

创建于 2014-07-08  ·  73评论  ·  资料来源: mopidy/mopidy

这不断出现,因为人们似乎真的很喜欢 ncmpcpp 的可视化工具

制作可靠的 FIFO 接收器的技巧是双重的。 您需要使用非阻塞写入,这意味着除非有读取器,否则打开写入套接字将失败,因此您也需要一个读取器。 其次,如果缓冲区因外部阅读器落后或没有而填满,则您的内部阅读器需要清除缓冲区。

下面的代码捕获了这个的基本要点,但仍然需要在错误处理方面做更多的工作。

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 

上面的代码现在需要与 GStreamer 集成才能真正做到这一点。 假设 0.10 这实际上是非常可行的,我犹豫的原因是我们正在计划迁移到 1.x 并且 gir 绑定不适合在 python 中制作元素。 对于 1.x 中的这段代码,问题归结为无法创建 BaseSink 期望找到的焊盘模板。 将其创建为普通元素可能是可行的,但您需要重新实现 BaseSink 的大部分处理方式,以确保您做对了。

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) 

请注意,我在测试时遇到的一个问题实际上是忘记匹配 ncmpcpp 预期的音频格式,因此请确保单声道/立体声确实匹配。

C-enhancement A-audio

最有用的评论

仅供参考,我向 ncmpcpp 添加了对 gstreamer 的udpsink ,因此现在可以直接使用它而无需使用 fifo hacks。

有关更多详细信息,请参阅https://github.com/ncmpcpp/ncmpcpp/commit/fb886f687014e22b2fe1477da855be5201063ea8

下面是预告片。 这是 mopidy + mopidy-spotify + mopidy-mpd + ncmpcpp。

https://user-images.githubusercontent.com/387658/102549720-e41bf980-40bc-11eb-8127-70889011e52f.mp4

所有73条评论

这去哪儿了? 这会添加到主包中吗?

由于我们需要将其转换为 GStreamer 1.0,因此尚未对此进行处理,到目前为止,我的所有实验都发现了在 Python 中执行自定义元素时存在的问题。 也许还有其他方法可以解决所有问题,但我没有时间做这件事。

我希望看到添加 FIFO 支持:)

我刚刚发现这是在寻找一种让 ncmpcpp 的音乐可视化工具与 mopidy 一起工作的方法。 我赞成。

是的,这就是我发现这个的原因。 真是太好了
能够可视化流媒体音乐,

2014-11-06 2:19 GMT-05:00 布莱克通知@github.com

我刚刚发现这是在寻找一种方法来让 ncmpcpp 的音乐可视化工具
与 mopidy 一起工作。 我赞成。


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -61936376。

有gstreamer可视化插件,你不能只用那些吗?
2014 年 11 月 6 日 08:35,“Diego Berrocal”通知@ github.com 写道:

是的,这就是我发现这个的原因。 真是太好了
能够可视化流媒体音乐,

2014-11-06 2:19 GMT-05:00 布莱克通知@github.com

我刚刚发现这是在寻找获取 ncmpcpp 音乐可视化工具的方法

与 mopidy 一起工作。 我赞成。


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -61936376。


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -62007426。

请注意,这些将在下一个版本中消失。

有人在做这方面的工作吗? 能够将 ncmpcpp 可视化工具与 mopidy 一起使用会非常好。

我不知道,我们可能不想将其作为 GStreamer 元素来执行,因为它会阻止我们迁移到 GStreamer 1.x。

IMO 也阻止了对输出的适当支持。

只是补充一点,我在尝试向 Mopidy/ncmcpp 添加可视化器支持时也遇到了这个问题。 即使目前没有工作,也希望在未来拥有这个。 我还要向那些为开源项目贡献时间的人致以最崇高的敬意。 :微笑:

理想情况下,这可以远程工作。 Mopidy 的强大之处在于它是一种可以在您的私有云中使用的解决方案。

通常,FIFO 不是一种非常便携的进程间通信方法,应避免在 IMO 中使用。 它们也有一些令人讨厌的副作用,在这个线程中已经提到。 我认为您最好亲自使用 UDP 接收器转储您的数据包......这是一个更通用的解决方案,可以轻松地适应在 Mopidy 之外写入 FIFO(如有必要)的内容......这是一个单一的一行 shell 脚本从 UDP 端口读取数据(使用 netcat)并将其写入 FIFO。

听起来不错。 可能是客户端谎言 ncmpcpp 也允许使用它作为输入。

另一个想法是直接使用 PulseAudio,因为它不需要 Mopidy 方面的额外实现。 我制作的 Docker 容器使用 TCP 通过网络访问 PulseAudio。 ncmpcpp 实际上可以直接使用它。

从我读到的内容来看,可视化器只是在从 FIFO 文件读取的样本块上运行 FFT。 我要说的一点是,您可以使用mkfifo在 Mopidy 之外创建一个 FIFO,然后使用netcat从 Mopidy 读取 UDP 数据并将输出从netcat重定向到先进先出文件。 因此,就ncmpcpp而言,没有什么需要改变的,它只是读取 FIFO 文件。

要实现您在 Mopidy 上的目标,不需要任何实现工作,因为您可以将音频输出属性更改为输出到 udpsink GStreamer 元素。 更有可能的是,您希望将它安排为“Tee”的一部分,该“Tee”输出到您的 ALSA/Pulse sink 和 udpsink。

以下应该工作......没有测试所以可能需要一些tweeking。

在 Mopidy 音频配置中:

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

在您的 Linux 主机上,启动 netcat 以在 localhost 上侦听端口 5555 上的 UDP 数据并将样本输出到 FIFO:

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

在您的 mpd.conf 中:

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

注意:如果您使用的是 PulseAudio 输出,则可以对其 TCP 方向连接模块执行类似操作。 但是,您可能需要对其在 TCP 连接顶部运行的任何协议进行逆向工程,例如,可能无法将其视为原始接收器。

感谢@liamw9534的分享。 我需要一段时间才能理解配置足以做到这一点,甚至知道我可以。 我会尝试将它添加到Docker 容器中,看看它是否有效。

如果您没有清空 fifo 的东西,这可能会遇到问题。 因为 netcat 将填充内核缓冲区然后失败。 根据 FIFO 的打开方式,您也可能会遇到问题,因为 FIFO 可能需要读取器存在才能可写:/

但是你可以调整我的 FifoStreamer 代码来接受 UDP 数据并为你处理这个,因为我希望已经处理了你可能遇到的大多数错误情况。

@adamcik如果您有一个工作脚本,我很乐意将其作为docker-ncmpcpp 的一部分供人们使用。 我还会使用上面的输出技巧将docker-mopidy默认情况下更改为在 UDP 上广播。

我在命令行上做了一些基本的实验,只要您使用连接超时,例如nc -kluw 1 127.0.0.1 5555 > /tmp/mopidy.fifo ,一切都可以正常工作。 这会强制 netcat 在最后一个连接断开(1 秒超时)后始终侦听新的源端口连接。

无论是否从 FIFO 文件读取任何内容,上述命令都有效,并且如果从 FIFO 文件读取的进程停止并关闭文件,则该命令也有效。

@wernight请参阅此错误的描述,这就是我拥有的所有代码。

仅对于腰带和大括号,我会将命令粘贴在 while 循环中,例如while :; do nc -kluw 1 127.0.0.1 5555> /tmp/mopidy.fifo; sleep 1; done - 如果它确实退出,它将在 1 秒延迟后再次启动。

@liamw9534你在那里有一个 mpd.conf。 我对此感到困惑。 除了 mopidy-mpd 之外,您还运行独立的 MPD 服务器吗?

@lrvick是的,我的错误,当然是考虑需要添加到 ~/.ncmpcpp/config 的配置

.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

(在此处添加了-p )。

~/.ncmpcpp/config

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

(也在wernight/docker-mopidywernight/docker-ncmcpp 中完成

然而,即使 Mopidy 的日志显示它理解output配置,它似乎也无法连接到 5555。 netstat在 5555 上也显示没有打开的 UDP。我不完全理解output行: tee是一个 bash 命令,其余的看起来像 Mopidy 的东西。

然而,我确实在播放音乐时发现了udp6 [::]:51307

output被解释为GstBin元素,该元素作为 Mopidy 的一部分传递给playbin2 - 在幕后,这只是一个 Gstreamer 管道,没什么特别的。 因此tee实际上是一个 Gstreamer 元素。 它与 shell 命令tee无关。

因此,您可以在命令行上执行以下操作来近似 Mopidy 内部发生的情况:

gst-launch audiotestsrc ! tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink port=5555 &

这将开始播放正弦音调。 然后运行以下命令:

nc -kluw 1 127.0.0.1 5555

然后我可以开始在我的显示器上看到很多奇怪的字符......这是从nc输出到标准输出的测试音频流。 这有效地证明了底层方法有效。 你能确认你可以复制相同的行为吗?

然后,您可以尝试将 FIFO 添加为第二步,并确认您可以将cat FIFO 添加到标准输出并看到相同的奇怪字符。

我还会仔细检查ncmpcpp所需的配置格式。 我简要地查看了https://wiki.archlinux.org/index.php/Ncmpcpp#Enabling_visualization ,可以看到可能需要的配置格式不同,例如,

visualizer_fifo_path = "/tmp/mpd.fifo"
visualizer_output_name = "my_fifo"
visualizer_sync_interval = "30" 
visualizer_in_stereo = "yes"
visualizer_type = "spectrum" (spectrum/wave)

我不使用ncmpcpp ,所以问题也可能在这里......

$ apt-get install gstreamer-tools
$ gst-launch audiotestsrc ! tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink port=5555 &
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstPulseSinkClock
$ nc -kluw 1 127.0.0.1 -p 5555
no connection : Connection timed out

(用nc ... -p否则我得到一个错误)

我确实听到了播放的声音。

你用的是什么发行版? 另外,当您键入nc -h ,输出是什么?

$ nc -h
OpenBSD netcat (Debian patchlevel 1.89-4ubuntu1)
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
      [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [hostname] [port[s]]
    Command Summary:
        -4      Use IPv4
        -6      Use IPv6
        -D      Enable the debug socket option
        -d      Detach from stdin
        -h      This help text
        -i secs     Delay interval for lines sent, ports scanned
        -k      Keep inbound sockets open for multiple connects
        -l      Listen mode, for inbound connects
        -n      Suppress name/port resolutions
        -P proxyuser    Username for proxy authentication
        -p port     Specify local port for remote connects
        -q secs     quit after EOF on stdin and delay of secs
        -r      Randomize remote ports
        -S      Enable the TCP MD5 signature option
        -s addr     Local source address
        -T ToS      Set IP Type of Service
        -C      Send CRLF as line-ending
        -t      Answer TELNET negotiation
        -U      Use UNIX domain socket
        -u      UDP mode
        -Z      DCCP mode
        -v      Verbose
        -w secs     Timeout for connects and final net reads
        -X proto    Proxy protocol: "4", "5" (SOCKS) or "connect"
        -x addr[:port]  Specify proxy address and port
        -z      Zero-I/O mode [used for scanning]
    Port numbers can be individual or ranges: lo-hi [inclusive]

我在 Ubuntu 上使用的nc不需要-p选项。 手册页还暗示将-p-l一起指定应该是错误的:

     -l      Used to specify that nc should listen for an incoming connection
             rather than initiate a connection to a remote host.  It is an error
             to use this option in conjunction with the -p, -s, or -z options.
             Additionally, any timeouts specified with the -w option are ignored.

使用Debian Wheezy。

以下是从安装 Docker开始的 Ubuntu 的完整步骤:

  1. 安装码头工人

$ wget -qO- https://get.docker.com/ | sh $ sudo gpasswd -a ${USER} docker

  1. 启用远程 PulseAudio
  2. 在 Debian 上运行:

$ docker run --rm -it \ -e PULSE_SERVER=tcp:$(hostname -i):4713 \ -e PULSE_COOKIE_DATA=$(pax11publish -d | grep --color=never -Po '(?<=^Cookie: ).*') \ debian:wheezy $ apt-get update && apt-get install -y netcat $ nc -h [v1.10-40] connect to somewhere: nc [-options] hostname port[s] [ports] ... listen for inbound: nc -l -p port [-options] [hostname] [port] options: -c shell commands as `-e'; use /bin/sh to exec [dangerous!!] -e filename program to exec after connect [dangerous!!] -b allow broadcasts -g gateway source-routing hop point[s], up to 8 -G num source-routing pointer: 4, 8, 12, ... -h this cruft -i secs delay interval for lines sent, ports scanned -k set keepalive option on socket -l listen mode, for inbound connects -n numeric-only IP addresses, no DNS -o file hex dump of traffic -p port local port number -r randomize local and remote ports -q secs quit after EOF on stdin and delay of secs -s addr local source address -T tos set Type Of Service -t answer TELNET negotiation -u UDP mode -v verbose [use twice to be more verbose] -w secs timeout for connects and final net reads -z zero-I/O mode [used for scanning] port numbers can be individual or ranges: lo-hi [inclusive]; hyphens in port names must be backslash escaped (e.g. 'ftp\-data'). $ nc -kluw 1 127.0.0.1 5555 UDP listen needs -p arg $ apt-get install -y net-tools gstreamer-tools gstreamer0.10-plugins-good $ echo -ne $(echo $PULSE_COOKIE_DATA | sed -e 's/../\\x&/g') >$HOME/pulse.cookie $ export PULSE_COOKIE=$HOME/pulse.cookie $ gst-launch audiotestsrc ! tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink port=5555 & $ nc -kluw 1 127.0.0.1 -p 5555 no connection : Connection timed out

尝试使用netcat-openbsd包,它提供:

$ nc -h
OpenBSD netcat (Debian patchlevel 1.105-7)
...

现在nc在播放音调时什么都不显示(这似乎更好):

$ nc -kluw 1 127.0.0.1 5555
(nothing here)

好的,打开两个终端并在第一个终端中运行:

nc -kluw 1 127.0.0.1 5555

然后在第二个终端运行:

nc -u 127.0.0.1 5555

在第二个终端的 stdin 上输入一些字符,然后按 ENTER。 您是否看到相同的字符出现在 stdout 的第一个终端中?

是的,有效。 甚至让它跨 Docker 工作:

$ docker run --rm --name nc1 -it my-debian-with-nc nc -kluw 1 0.0.0.0 5555
Hello

$ docker run --rm --link nc1:nc1 -it my-debian-with-nc nc -u nc1 5555
Hello

所以这并不能解释为什么nc没有显示gst-launch 。 但是我发现我需要设置host=SOMETHING才能让它跨容器工作。 这将是有问题的。 好像不能播。 但是,一旦它至少在单个容器上工作,我就可以解决这个问题。

啊哈! 如果我设置host=0.0.0.0就可以了!

您需要通过网络发送数据吗? 我假设你只需要本地机器上的数据包。 使用udpsink host=0.0.0.0 port=5555将在您的网络上到处广播数据包。 可能不是你想要的......

你应该可以说host=127.0.0.1来限制数据包到本地环回。

因此,我怀疑真正的问题在于默认路由配置。 默认情况下,在您的系统上,传出数据包被引导到不同的接口。 可能是 gstreamer 元素的不同版本或 IP 路由设置的差异。

从容器中,我不得不使用 0.0.0.0 或可能的机器 IP。 即使在单个机器/容器上,默认设置也不起作用。

但是是的,我现在必须使用网络,因为将 ncmpcpp 和 mopidy 保存在单独的 Docker 容器中是一种很好的做法,这意味着它们位于不同的网络上。 这对安全和隔离等确实有好处,但它会带来一些麻烦:

ncmpcpp 客户端连接到 MPD 服务器以请求音乐流媒体,然后才知道 ncmpcpp 的 IP,并且 UDP 数据包应该广播到它的 IP; 但目前 IP 是在 Mopidy 配置中硬编码的。

我现在没有解决办法。 我在想解决办法:

  • 在 Mopidy 中创建 FIFO 并与 ncmpcpp 共享,但恐怕没有任何东西可以清除 FIFO,这是个大麻烦。 共享文件也不像网络套接字那么干净。
  • 本地守护进程监控连接并将 UDP 流量转发到找到的客户端 IP; 黑客。
  • UDP SSH 隧道,但这很复杂,添加了无用的加密,添加了另一个守护进程……糟糕!
  • 查看代码以查看udpsink主机是否可以默认为第一个客户端的 IP,甚至更好地为所有连接的客户端的 IP
  • 通过--net=container:NAME_or_ID告诉 Docker 共享主机,这增加了另一个参数供用户输入,但这会简化很多!

有针对这种循环依赖的解决方案。 仍然感觉像一个可怕的黑客,但最终用户应该很容易使用它。 感谢 liamw9534 对我陌生的nc命令的帮助。

除了There is no output named "my_fifo"!之外,FIFO 正在工作。 似乎名称必须与mdp.conf中的名称匹配:

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

如果我知道如何将此音频输出添加到 Mopidy,我可能会尝试共享 FIFO 文件。 恶心(一个简单的可视化工具)似乎有相同的要求。

我找到visualizer_output_name文档

  • ncmpcpp 需要以下参数来确定哪个输出为可视化器提供数据,从而允许在可视化和声音之间进行同步,因为目前它存在一些问题。
  • fifo 输出,其格式参数必须设置为 44100:16:1 单声道可视化或 44100:16:2 立体可视化

我不确定你所说的“在不同的网络上”是什么意思。 如果您想将音频流量隔离到本地机器,那么您应该将127.0.0.1用于udpsink 。 如果您选择0.0.0.0那么它将使用默认路由引导数据包,这可能意味着通过网络发送 UDP 数据包......总的来说,我会说这是一个坏主意,因为网络流量将消耗大量带宽,即 2 x 16 x 44100 = 1.41 Mbps。

理论上,无论udpsink使用哪个网络接口,都应该可以使用0.0.0.0配置nc udpsink 。 这将侦听所有网络接口。 只要您不对不同网络接口上的其他服务使用相同的 IP 端口号,就可以了。

我使用了我的最后一个建议并将它们放在同一个网络上。 无论如何,这些网络都是本地的,这只是逻辑上的分离。 这适用于构建 FIFO,只是 ncmpcpp 不想要它(请参阅我之前的回复,上面的 2)。

对那个频道名称有什么想法吗? 或者如果有另一种方法可以像mpd.conf这样的 FIFO ? 没有似乎根本不起作用。

我认为mpd.conf仅用于 MPD 守护程序配置。 在这种情况下,这应该是多余的,因为 mopidy 是 MPD 守护程序,而您的 docker 正在创建 FIFO 文件。 在这种情况下,唯一需要做的就是确保.ncmpcpp/config与客户端匹配,对吗?

的种类。 我不知道它到底在做什么。 但是正如您所看到的, visualizer_output_name = "my_fifo" 必须匹配audio_output { name "my_fifo" } 。 当前 ncmpcpp 显示There is no output named "my_fifo"visualizer_output_name的描述只是上面的 5 个帖子。 看起来它实际上是以某种方式直接连接到要同步的输出。

我不使用任何这些,但在我看来visualizer_output_name应该匹配您的 MPD(协议,而不是程序)输出之一(即mpc outputs某些内容)。 Mopidy 目前不允许可配置的输出,并且只有一个 MPD 输出:“静音”。

如果可能,您可能希望取消设置visualizer_output_name

试过不设置。 仍然没有可视化工具可见。 我想知道udpsink的输出格式:应该是44100:16:2可视化工具才能工作( ncmpcppnausea )。

试过Mute以防万一,得到了一个非常有趣的体验:它只是静音,没有显示错误,也没有显示可视化工具。 或者更确切地说,它禁用了Mute输出。

我确实想知道在何处为可视化器执行 FFT 函数。
它是在 FIFO 的输出端还是在 FIFO 的输入端执行? 你
需要检查 MPD 客户端代码以查看它如何处理 FIFO 数据。

有没有办法支持两者之一,仅用于测试,即使它通常会创建一个巨大的文件。

你也不需要支持。 你需要找出FFT在哪里
应该做,然后选择正确的方法。 如果 FFT 是
在可视化器中完成,那么它只会完全浪费精力
再次实施。

2015年5月在15:09 13日,沃纳Beroux [email protected]写道:

有没有办法支持两者之一,仅用于测试,即使它会
通常会创建一个巨大的文件。


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -101676033。

FFT 由可视化器完成,它需要 FIFO 中的特定音频格式才能为此工作。 参考: http :

好 - 那么它没有理由不工作! 你有没有做过
运行标准 MPD 守护程序的系统与
本地 ncmpcpp 客户端? 如果在两者中重命名 FIFO 文件名会发生什么
配置文件? 它仍然有效吗? 只是想看看是否
硬编码路径存在于某处...

2015年5月在15:57 13日,沃纳Beroux [email protected]写道:

FFT 由可视化工具完成,它需要特定的音频格式
在 FIFO 中为此工作。 参考: http :


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -101702624。

我的评论基于ncmpcpp 源

Mopidy 的静音输出默认禁用,即音频不静音。 ncmpcpp 可视化器将获取您提供的输出,禁用它(无效)然后启用它,从而使音频静音。 可以说他们应该只切换两次。

音频格式错误很有可能。 与@adamcik在上面的代码中不同,您的 gstreamer 管道中没有任何内容可以确保它是正确的。

很难看出格式有什么问题……它是 16 位签名的
整数。 可能发生的最坏情况是您交换 L/R 通道?

2015 年 5 月 13 日 16:33,Nick Steel通知@github.com 写道:

我的评论基于 ncmpcpp 源
http://git.musicpd.org/cgit/mirror/ncmcpp.git/tree/src/visualizer.cpp。

Mopidy 的静音输出默认禁用,即音频不静音。
ncmpcpp 可视化器将获取您提供的输出,禁用它(不
效果),然后启用它,从而使音频静音。 可以说他们应该
只需切换两次。

音频格式错误很有可能。 你有
与@adamcik 不同,您的 gstreamer 管道中没有任何内容可以确保它是正确的
https://github.com/adamcik在他上面的代码中有。


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -101716947。

即使字节顺序是错误的,您也可能只期望 FFT
输出产生错误的频率响应......但你仍然会看到
某物。

2015 年 5 月 13 日 16:37,利亚姆·威金斯[email protected]写道:

很难看出格式有什么问题……它是 16 位签名的
整数。 可能发生的最坏情况是您交换 L/R 通道?

2015 年 5 月 13 日 16:33,Nick Steel通知@github.com 写道:

我的评论基于 ncmpcpp 源
http://git.musicpd.org/cgit/mirror/ncmcpp.git/tree/src/visualizer.cpp。

Mopidy 的静音输出默认禁用,即音频不静音。
ncmpcpp 可视化器将获取您提供的输出,禁用它(不
效果),然后启用它,从而使音频静音。 可以说他们应该
只需切换两次。

音频格式错误很有可能。 你有
您的 gstreamer 管道中没有任何内容来确保它是正确的,不像
@adamcik https://github.com/adamcik在他上面的代码中有。


直接回复此邮件或在 GitHub 上查看
https://github.com/mopidy/mopidy/issues/775#issuecomment -101716947。

是的,所以也许是因为启用 Mopidy 的静音输出意味着 udpsink 不会发送任何数据。

cat /tmp/mdp.fifo (如上从 UDP 创建)正确显示恒定的数据流。

我查看了可视化工具 ncmpcpp 代码:

  1. 打开文件O_RDONLY | O_NONBLOCK
  2. 从顶部读取; 鉴于它在我的 mopidy 配置中设置为立体声,它应该是 44100:16:2。

任何人也可以从我的分支尝试(安装 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

由于 -k 对我不起作用,我不得不花费相当长的时间来处理 netcat,但这是我想出的在歌曲切换时自动重新启动它的方法:

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

其他选项基本上如上所述。

@S0lll0s @wernight netcat -k 对我也不起作用,必须在歌曲更改后重新启动。 虽然您的解决方案有效,但我发现 socat 效果更好:

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

对于 arch linux 用户:

要获得带有-k支持的nc ,您需要安装openbsd-netcat包,但它对我也不起作用,因此请尝试使用@SjRNMzU的脚本 - 您需要socat包来运行它。

@johnhamelink (我假设您正在根据您的评论运行 Arch)在您使用socat解决方案暂停歌曲后,您是否遇到了可视化工具试图“赶上”的问题?

@theos-space 我不能说我已经注意到我自己

我在 Arch 上,无法让它与ncgnuopenbsd )或socat 。 此外,我无法使用nc -kluw 1 127.0.0.1 5555读取gst-launch-1.0 ... udpsink port=5555 nc -kluw 1 127.0.0.1 5555 ,因为它不会在屏幕上打印任何内容。

可以确认这适用于 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:

在系统启动时启动socat:

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(注意必须为 udpsink 定义主机):

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

对于 Arch 您必须使用 fifo 支持编译 ncmpcpp,请在此处查看: https ://bbs.archlinux.org/viewtopic.php?id=99915

这是我在阅读其余的线程 + 文档 + 联机帮助页 + 各种博客后的工作 Arch 设置。 我将 Mopidy 作为系统服务运行,并通过 TCP 将音频发送到用户服务 PulseAudio。 我已经包含了一些额外的注释,希望对经验不足的人有所帮助。

套餐

所有这些都来自官方 Arch 存储库:

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

设置

启用 mopidy 系统服务:

sudo systemctl enable mopidy.service

用指向用户配置的符号链接替换 ​​mopidy 的系统配置,以便于编辑(可选):

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

创建fifo文件:

mkfifo "/tmp/mpd.fifo"

配置

~/.config/mopidy/mopidy.conf (或/etc/mopidy/mopidy.conf如果您没有创建符号链接):告诉 mopidy 将音频发送到在本地主机上侦听的pulseaudio 服务器和本地主机上的 UDP 接收器:5555

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

~/.ncmpcpp/config :告诉 ncmpcpp 在哪里可以找到它需要收听的 fifo 文件,以及其他一些杂项设置

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

~/.config/pulse/default.pa :告诉 pulseaudio 接受来自本地主机的 TCP 上的音频(该设置可能已经存在并且可以取消注释)

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

~/.zshrc (也应该在~/.bashrc ):创建一个包装函数“nplayer”来处理使用ncmpcpp启动和停止netcat ncmpcpp

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

这是做什么的:

  • 定义一个函数,其子外壳包含其全部内容
  • 在后台启动netcat进程以侦听发送到 UDP 接收器的音频数据并将其重定向到之前创建的 fifo。 标志:

    • -k在当前连接完成后继续监听

    • -l开启聆听模式

    • -u开启UDP模式

    • -w NUM在 NUM 秒后超时空闲连接(在这种情况下为 1 秒)

  • ncmpcpp进程终止并导致函数子 shell 退出时,设置一个 EXIT 陷阱来终止netcat进程
  • 在前台启动ncmpcpp进程

我在 Manjaro(拱形发行版)上运行 mopidy。 我无法通过 socat 或 netcat 获取任何输出。 不过,我能够观察到带有 tcpdump 的数据包:
sudo tcpdump -i lo -n udp port 5555 -XX

我花了很长时间,如果没有@mosbasik我就不会发现这个问题。
问题是在 udpsink 之后没有host=127.0.0.1 ,为什么这适用于其他人而不是我,我不知道。 但是,如果您没有得到任何输出,则可能是这种情况。 这两个对我有用:

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

或者

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

附带说明:我无法让pulsesink工作,所以我不得不将它留在autoaudiosink ,这也是我之前设置的。 然而,由于某种原因,可视化器似乎真的很慢,我不确定这是否是因为autoaudiosink重新启动后工作完美......虽然仍然有点慢。 使用pulselink,它一直抱怨gstreamer插件。 即使在(我假设)我在官方 Arch 存储库上安装了 gst 的每个插件包之后。 注意flump3decmad


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

我在尝试让 udpsink 与 Mopidy 和所有远程 ncmpcpp 客户端一起工作时遇到了一个问题。 Mopidy 是在 docker 环境中使用 MacVLAN 设置的。 我可以成功看到容器上的端口。

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!

目前 Mopidy 正在使用以下配置:

[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

关于如何使用 netcat 将原始数据成功导入 mpd.fifo 的任何想法? 使用以下方法不起作用,我想是因为我以错误的方式使用 netcat。 一些研究没有提供任何答案,所以希望有人能指出我正确的方向。

#!/bin/bash

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

我收到以下错误:

nc: Can't assign requested address

关于如何让它发挥作用的任何想法?

干杯!

仅供参考,我向 ncmpcpp 添加了对 gstreamer 的udpsink ,因此现在可以直接使用它而无需使用 fifo hacks。

有关更多详细信息,请参阅https://github.com/ncmpcpp/ncmpcpp/commit/fb886f687014e22b2fe1477da855be5201063ea8

下面是预告片。 这是 mopidy + mopidy-spotify + mopidy-mpd + ncmpcpp。

https://user-images.githubusercontent.com/387658/102549720-e41bf980-40bc-11eb-8127-70889011e52f.mp4

@arybczak 太棒了! 您应该将此发布到https://discourse.mopidy.com/c/show-and-tell/9

@adamcik 这是否意味着这个近 7 年的问题已被“弃用”,以支持更好地解决引发它的现实世界问题(支持 ncmpcpp 中的可视化)?

@pspeder ,你到底是什么意思? 使用https://github.com/mopidy/mopidy/issues/775#issuecomment -747725806 有问题吗?

@kingosticks只是建议关闭这个问题🙂

我同意这一点。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

kingosticks picture kingosticks  ·  12评论

handsomegui picture handsomegui  ·  12评论

voidmann picture voidmann  ·  11评论

godzillamesel picture godzillamesel  ·  6评论

ice-bear-forever picture ice-bear-forever  ·  6评论