如何设置到DLNA兼容设备的实时音频流?


53

有没有一种方法可以将声卡的实时输出从我们的12.04.1 LTS amd64桌面流式传输到我们网络中的DLNA兼容外部设备?使用Rygel,miniDLNA和uShare在共享目录中选择媒体内容总是可以的-但到目前为止,我们完全无法通过DLNA将实时音频流传输到客户端。

Pulseaudio声称拥有DLNA / UPnP媒体服务器,该服务器与Rygel一起可以做到这一点。但是我们无法使其运行。

我们遵循live.gnome.org中的步骤,此处的答案以及另一本类似的指南中的步骤


12.04 LTS中,我们可以选择本地音频设备,也可以选择DLNA客户端中的GST启动流,但是Rygel显示以下消息,并且客户端声明其已到达播放列表的末尾:

(rygel:7380): Rygel-WARNING **: rygel-http-request.vala:97: Invalid seek request

无法在客户端上收听实时音频流。


只有将发行版升级到14.04 LTS之后,我们才可以从下面的答案中概述的设置中选择DLNA渲染器上的实时流。尽管如此,我们启动rygel 之后仍需要选择已建立的流并且无法将新的流推入UPnP设备。音频元数据未传输。


还有其他方法可以将声卡的音频作为实时流发送到DLNA客户端吗?


您可以避免使用接收器设备进行DLNA流传输吗?我的解决方案是通过HTTP传递Pulseaudio流,请参阅此处的更多信息:sandalov.org/blog/1441
DmitrySandalov 2012年

抱歉,不,我确实希望DLNA能够正常工作,因为DLNA仅广泛应用于各种客户端(电视,AV接收机,Blueray播放器等)。
塔卡特2012年

Takkat,我正在谈论的解决方案解决了向AVR流式传输的问题。如果您真的要启动DLNA服务器,我在12.04上对rygel + pulseaudio有过积极的经验(在“ pacmd load-module module-http-protocol-tcp”之后),在12.10上,我收到了相同的“无效查找请求”警告。
DmitrySandalov

@DmitrySandalov:如果您共享有关如何成功设置Rygel以便实时流式传输Pulseaudio输出的详细信息,那真是太酷了。
塔卡特2012年

Answers:


63

脉冲音频-DLNA

我创建了一个小服务器,该服务器可以发现网络中的所有upnp渲染器,并将它们作为接收器添加到Pulseaudio。因此,您可以通过pavucontrol控制每个应用程序以在upnp设备上播放。

这是我在Linux下处理upnp设备时一直想要的那种舒适感。

该应用程序可以从源代码安装,也可以从git下载的 DEB软件包安装,或者在我们通过以下方式将项目的官方ppa:qos / pulseaudio-dlna添加到我们的源代码之后安装:

sudo apt-get update && sudo apt-get install pulseaudio-dlna

然后,从命令行使用以下选项运行pulseaudio-dlna:

pulseaudio-dlna [--host <host>] [--port <port>] [--encoder <encoder>] [--renderer-urls <urls>] [--debug]
pulseaudio-dlna [-h | --help | --version]

另请参见pulseaudio-dlna“关于”

当存在DLNA渲染器时,我们可以从声音菜单中选择它作为输出接收器:

在此处输入图片说明


3
很棒的应用程序-谢谢!在包括三星智能电视(UE40ES6100)的设备上正常工作。请注意:我们还需要python-requests作为依赖项,我们可以从默认音频控件中选择渲染器-无需安装pavucontrol。
塔卡特2015年

很高兴你喜欢它。我刚刚更新了自述文件。感谢您的提示!
Massimo 2015年

2
很好的解决方案。谢谢。但是我有一个问题:播放延迟为几秒钟(在VLC中按“暂停”后10秒钟)。这是DLNA的“功能”还是有什么方法可以减少它?DLNA对视频播放或游戏没有意义吗?:(
JPT 2015年

2
延迟来自填充HTTP缓冲区。如果您的连接出现问题(wifi弱等),它可以保持流播放。如果要减少延迟,请使用需要大量带宽(wav)的编解码器以更快地填充该缓冲区。电缆连接总是有帮助的。否则,这是针对您的制造商固件实施的。例如,我对Cocy的延迟时间约为1秒。Sonos使用wav播放1:1秒,使用mp3:5秒。全部通过电缆连接。但是您不会完全摆脱它。主要用途是音乐和有声读物。一切都不需要同步。
Massimo 2015年

1
@JPT和其他所有人都在寻找一种解决延迟的方法(对我来说是10s):使用shairport-sync,我在RaspberryPi上与DLNA接收器并行运行一个AirPlay接收器,必须说延迟要短得多(〜 2s启动;立即停止)。话虽如此,这要感谢Massimo,因为无需担心延迟,pulseaudio-dlna就像一个魅力,安装起来真的很简单!(AirPlay的是相当有点难以设置为我。)
巴鲁

8

Pavucontrol是此拼图游戏中缺少的项目!我也已经正确设置了所有内容,并且外接设备(LG TV)显示正在播放声音,但没有听到任何声音。今天,我安装了pavucontrol,当我打开它时,我发现可以通过DLNA服务器引导声音。DLNA选项仅在播放器将声音输出到pulseaudio时显示。 在此处输入图片说明


感谢您分享这个。您是如何设置DLNA服务器的?对我而言,Aym Rygel退出时无济于事。
塔卡特2012年

我只有正常设置。我遵循了您在帖子中提到的相同链接。[GstLaunch] enabled = true launch-items = audiotestsrc; audiotestsrc-title =桌面实时流!audiotestsrc-mime =音频/ mpeg audiotestsrc-launch = pulsesrc设备= upnp.monitor!lamemp3enc目标=质量质量= 6
2012年

奇怪的。有了Rhythmbox,分段错误就消失了,但我仍然只能Invalid seek request从Rygel 那里得到。媒体目录在那里,但我的GST流始终为EOF。
塔卡特2012年

很棒的附加功能,它使您可以为每个可以播放音频的应用设置接收器!我可以在立体声音响上听音乐,并在计算机上保留视频或游戏声音。谢谢!
弹簧加载

当所有人都连接并播放但缺少声音时,这解决了我的问题!
easwee

4

抱歉,Rygel帮不了您,但是可能有其他替代方法可能对您有用。

原理是获得一个程序,将流录制到音频文件,然后使用自定义配置启动miniDLNA,该配置指向流所在的目录。

示例:假设我们正在〜/ stream /中工作。创建〜/ stream / minidlna.conf

network_interface=wlan0
media_dir=/home/<user>/stream/
friendly_name=Live Audio Stream
db_dir=/home/<user>/stream/
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg
inotify=no
enable_tivo=no
strict_dlna=no
notify_interval=900
serial=12345678
model_number=1

然后将流保存到该目录中的音频文件。谷歌搜索“ FFmpeg录制声卡音频”产生了此命令

ffmpeg -f alsa -i default -acodec flac ~/stream/OutputStream.flac

但是我运气不好。另一个选择是vlc,因为您有可用的GUI,但这不起作用。

然后在另一个终端窗口中启动miniDLNA:

minidlna -d -f ~/stream/minidlna.conf -P ~/stream/minidlna.pid

应该找到OutputStream.flac,然后可以从您的网络设备访问它。

希望如果您还没有解决,那么可以给您一些想法。


1
有前途的方法-谢谢-但是需要进一步完善。今天通过miniDLNA的快速测试,我的DLNA客户端无法识别流文件。另外,ffmpeg产生的流似乎很差(静态噪声)。我在,让你知道。
塔卡特2012年

到目前为止,我们可以使用ffmpeg或avconv从音频接收器生成flac或mp3音频文件。但是,除非我们退出录制,否则miniDLNA将无法识别此文件。然后,在录制另一个实例的同时,我们可以在DLNA客户端上再次打开此文件,但是流始终从录制的开始开始,并在开始监听客户端时停止。任何想法如何克服这个?
塔卡特2012年

因此,您是说一旦中断ffmpeg进程以停止记录,那么miniDLNA才可以识别该文件吗?另外,音频质量更好吗?我将在计算机上尝试一下,看看是否可以再次使用它。(我去年曾进行过类似的工作以动态转换电影)
mtdevans,2012年

是的,首先。第二次,我可以从客户端访问它,但是它从头开始(即,无论何时我开始录制),都从中间开始(即,从开始录制到在客户端开始接收之间的确切时间之后)。音频现在很好,不得不禁用双工。
塔卡特2012年

4

我必须将“我听到的内容”流式传输到DLNA渲染器(如WDTV)的一个想法是,将带有VLC的流作为HTTP流pulse://alsa_output.xxx.monitor作为服务器输入,并将其转码为MP3或FLAC。然后,我想使用一些DLNA控制点让渲染器播放流。VLC确实正确地提供了转码流,但是它不允许设置mime类型,因此渲染器拒绝播放它。

下一个想法是用python编写一个HTTP服务器来代替该流。它使用来从脉冲中获取音频流parec,使用flac(或lame您想要的任何形式)对其进行编码,并正确设置mime类型。

它与以下(非常简单)的脚本一起使用:

#!/usr/bin/python

import BaseHTTPServer
import SocketServer
import subprocess

PORT = 8080
# run "pactl list short |grep monitor" to see what monitors are available
# you may add a null sink for streaming, so that what is streamed is not played back locally
# add null sink with "pactl load-module module-null-sink"
MONITOR = 'null.monitor'
MIMETYPE = 'audio/flac'
ENCODER = 'flac - -c --channels 2 --bps 16 --sample-rate 44100 --endian little --sign signed'
BUFFER = 65536

class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_HEAD(s):
    print s.client_address, s.path, s.command
    s.send_response(200)
    s.send_header('content-type', MIMETYPE)
    s.end_headers()
def do_GET(s):
    s.do_HEAD()
    pa = subprocess.Popen('parec -d {} | {}'.format(MONITOR, ENCODER), shell = True, bufsize = BUFFER, stdout = subprocess.PIPE)
    while True:
        data = pa.stdout.read(1024)
        if len(data) == 0: break
        s.wfile.write(data)
    print 'stream closed'


httpd = SocketServer.TCPServer(("", PORT), Handler)

print "listening on port", PORT

try:
httpd.serve_forever()
except KeyboardInterrupt:
pass

httpd.server_close()

调整参数,运行它,然后将DLNA渲染器指向您的计算机。它适合我使用WDTV作为渲染器,以及使用BubbleUPnP作为控制点的Android手机(在将新项手动添加到播放列表时,您可以键入流URL)。但它应可与任何DLNA兼容设备一起使用。


4

注意:此解决方案有效,但是Massimo提出了一种更新且可能更好的解决方案

为完整起见,这是Ubuntu 14.04(也已通过测试并在15.04上运行)的答案:

  1. 安装任何需要的软件包: sudo apt-get install rygel rygel-preferences rygel-gst-launch

  2. 创建~/.config/rygel.conf包含以下内容的文件:

    [GstLaunch]
    enabled=true
    title=@REALNAME@'s stream
    launch-items=myaudioflac;myaudiompeg
    
    myaudioflac-title=FLAC audio on @HOSTNAME@
    myaudioflac-mime=audio/flac
    myaudioflac-launch=pulsesrc device=upnp.monitor ! flacenc quality=8
    
    myaudiompeg-title=MPEG audio on @HOSTNAME@
    myaudiompeg-mime=audio/mpeg
    myaudiompeg-launch=pulsesrc device=upnp.monitor ! lamemp3enc target=quality quality=6
    
    [Playbin]
    enabled=true
    title=Audio/Video playback on @REALNAME@'s computer
    
    [general]
    interface=
    upnp-enabled=true
    
    [MediaExport]
    uris=
    
  3. 从命令行执行以下命令(如果需要,可以将其放入脚本中):

    pactl load-module module-http-protocol-tcp
    pactl load-module module-rygel-media-server 
    rygel &
    
  4. 运行paprefs命令,并确保“网络服务器”选项卡上的两个DLNA选项都已启用(选中)。

  5. 在计算机上播放一些音频。运行pavucontrol程序,然后在“播放”选项卡上,将输出设备更改为“ DLNA / UPnP Streaming”。

此时,您应该能够从DLNA客户端(渲染器/控制点)播放MPEG和FLAC流。

注意:您可能需要重新启动计算机(或重新启动脉冲)才能开始工作。


3

亚当的python脚本正是我所需要的。辉煌。带有gst-launch的Rygel不适用于我的渲染器之一,但此脚本可同时用于这两个渲染器。就我而言,我要从squeezelite(用于squeezebox)输入音频流,然后发送到渲染器。如果需要的话,该脚本还可以原始形式工作,以从PulseAudio监视器获取输入。

几乎不了解这些,我设法对脚本进行了一些补充:

i)允许它从Shell脚本运行并以SIGTERM / SIGKILL终止(“ except”语句现在包括“ systemexit”)

ii)允许脚本停止并重新启动,然后重新使用同一端口(因为重新启动的脚本倾向于失败,即如果渲染器仍将其打开则无法打开该端口)-(allow_reuse_address = True语句)

iii)制作一个从stdin输入并使用sox重新采样以wav格式输出的版本(在端口8082上)

所以我的版本看起来像:

#!/usr/bin/python

import BaseHTTPServer
import SocketServer
import subprocess

PORT = 8082

MIMETYPE = 'audio/x-wav'
BUFFER = 65536

class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
  def do_HEAD(s):
    print s.client_address, s.path, s.command
    s.send_response(200)
    s.send_header('content-type', MIMETYPE)
    s.end_headers()
  def do_GET(s):
    s.do_HEAD()
    pa = subprocess.Popen('sox -t raw -r 96000 -b 24 -L -e signed -c 2 - -t wav -r 44100 -b 16 -L -e signed -c 2 - ', shell = True, bufsize = BUFFER, stdout = subprocess.PIPE)
    while True:
        data = pa.stdout.read(1024)
        if len(data) == 0: break
        s.wfile.write(data)
    print 'stream closed'

SocketServer.TCPServer.allow_reuse_address = True
httpd = SocketServer.TCPServer(("", PORT), Handler)

print "listening on port", PORT

try:
 httpd.serve_forever()

except (KeyboardInterrupt, SystemExit):
 pass

httpd.server_close()

1
我发现此脚本有一些小问题。
pastim 2014年

@Adam-经过几次试验,我发现此程序存在一些小问题。但是,最大的问题是,在与发送的数据量成正比的时间之后,流停止并显示错误32(管道断开)。对于质量为24/96000的视频流,这仅需要一个多小时。在24/192000,时间超过30分钟。对于CD质量,超过3小时。通过在渲染器上再次选择流,该流再次开始。我相信解决方案可能是“块编码”。我想知道是否有人制作了分块的版本。
pastim 2014年

1

不知道这是否对您现在有用,但是我写了一篇有关使它在Ubuntu 12.10上工作的文章:

http://dpc.ucore.info/blog/2012/11/07/dlna-streaming-in-ubuntu-12-dot-10/


感谢您分享此内容-到目前为止,这正是我一直失败的原因。从本站点的设计中,我们希望鼓励您概述所采取的步骤(除了仅将链接发布到博客中),因为链接可能会随着时间的流逝而消失,从而使您的答案无用。一旦能够进行测试,我会尽快与您联系。
塔卡特2012年

到目前为止,这是我的观察结果:在12.04中从客户端选择音频流时,按照您的指南将Rygel与SEGFAULT崩溃。在12.10中,我们无法使用GST-Launch创建流。缺少什么?
塔卡特

问题是关于12.04,这个答案是针对Ubuntu 12.10的,否则我会投票赞成。:)
jdthood 2012年

未来的人:这个链接已经烂了。:P
datashaman

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.