¿Cómo configuro transmisiones de audio en vivo en un dispositivo compatible con DLNA?

54

¿Hay alguna manera de transmitir la salida en vivo de la tarjeta de sonido desde nuestro escritorio 12.04.1 LTS amd64 a un dispositivo externo compatible con DLNA en nuestra red? Seleccionar contenido multimedia en directorios compartidos usando Rygel, miniDLNA y uShare siempre está bien, pero hasta ahora no hemos podido transmitir una transmisión de audio en vivo a un cliente a través de DLNA.

Pulseaudio afirma tener un servidor de medios DLNA / UPnP que, junto con Rygel, se supone que debe hacer precisamente esto. Pero no pudimos hacerlo funcionar.

Seguimos los pasos descritos en live.gnome.org , esta respuesta aquí, y también en otra guía similar .


En 12.04 LTS podemos seleccionar el dispositivo de audio local, o nuestra transmisión de lanzamiento GST en el cliente DLNA, pero Rygel muestra el siguiente mensaje y el cliente indica que llegó al final de la lista de reproducción:

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

No había forma de escuchar transmisiones de audio en vivo en el cliente.


Solo después de una actualización de distribución a 14.04 LTS pudimos seleccionar una transmisión en vivo en nuestros renderizadores DLNA de la configuración bien descrita en la respuesta a continuación . Aún así, necesitábamos seleccionar una secuencia establecida después de que comenzamos rygel y no pudimos enviar una nueva secuencia a nuestros dispositivos UPnP. Los metadatos de audio no se transmitieron.


¿Hay alguna otra alternativa para enviar el audio de nuestra tarjeta de sonido como transmisión en vivo a un cliente DLNA?

Takkat
fuente
¿Puedes evitar la transmisión DLNA con tu dispositivo receptor? Mi solución es pasar la secuencia de pulseaudio a través de HTTP, vea más aquí: sandalov.org/blog/1441
DmitrySandalov
Lo sentimos, no, realmente quiero que DLNA funcione porque DLNA solo se implementa ampliamente en varios clientes (televisores, receptores AV, reproductores Blueray, etc.).
Takkat
Takkat, la solución de la que estoy hablando resolvió el problema de la transmisión a mi AVR. Si realmente desea iniciar un servidor DLNA, tuve una experiencia positiva con rygel + pulseaudio el 12.04 (después de 'pacmd load-module module-http-protocol-tcp'), el 12.10 recibí las mismas advertencias de 'Solicitud de búsqueda no válida' .
DmitrySandalov
@DmitrySandalov: sería realmente genial si compartiera detalles sobre cómo logró configurar Rygel para transmitir en vivo la salida de pulseaudio.
Takkat

Respuestas:

63

Pulseaudio-DLNA

Creé un pequeño servidor que descubre todos los renderizadores upnp en su red y los agrega como sumideros a pulseaudio. Para que pueda controlar cada aplicación a través de pavucontrol para jugar en sus dispositivos upnp.

Ese es el tipo de comodidad que siempre quise al tratar con dispositivos upnp en Linux.

La aplicación se puede instalar desde la fuente o el paquete DEB descargable desde git , o después de haber agregado el ppa oficial del proyecto : qos / pulseaudio-dlna a nuestras fuentes con:

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

Luego ejecutamos pulseaudio-dlna desde la línea de comando con las siguientes opciones:

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

Consulte también pulseaudio-dlna "Acerca de" para obtener más información.

Cuando había un renderizador DLNA presente, podemos seleccionarlo del menú de sonido como un sumidero de salida:

ingrese la descripción de la imagen aquí

Massimo
fuente
3
Gran aplicación, ¡gracias! Funcionó bien en mis dispositivos, incluido un Samsung Smart TV (UE40ES6100). Solo una nota: también necesitábamos python-requestscomo dependencia y podríamos seleccionar el renderizador de los controles de audio predeterminados; no es necesario instalar pavucontrol.
Takkat
Me alegra que te guste. Acabo de actualizar el archivo README. ¡Gracias por la pista!
Massimo
2
Gran solución Gracias. Pero tengo una pregunta: hay un retraso de reproducción de varios segundos (10 segundos después de presionar pausa en VLC). ¿Es esta una "característica" de DLNA o hay alguna forma de reducirla? ¿Entonces DLNA no tiene sentido para reproducción de video o juegos? :(
JPT
2
El retraso proviene de llenar el búfer HTTP. Mantiene la transmisión en caso de que su conexión tenga problemas (wifi débil, etc.). Si desea reducir el retraso, use un códec que necesite mucho ancho de banda ( wav ) para llenar ese búfer más rápido. La conexión por cable siempre ayuda. De lo contrario, esto es muy específico para la implementación del firmware de su fabricante. Por ejemplo, tengo un retraso con Cocy de aproximadamente 1 segundo. Sonos Play 1 con wav: 1 segundo, con mp3: 5 segundos. Todo conectado por cable. Pero no lo eliminarás por completo. El propósito principal es la música y los audiolibros. Todo lo que no necesita estar sincronizado.
Massimo
1
@JPT y todos los demás que buscan una manera de solucionar el retraso (10 segundos para mí): usando shairport-sync estoy ejecutando un receptor AirPlay en mi RaspberryPi en paralelo al receptor DLNA y debo decir que los retrasos son mucho más cortos (~ 2 s para iniciar; parar es inmediato). Dicho esto, muchas gracias a Massimo porque, olvidando el retraso, pulseaudio-dlna funciona de maravilla y es realmente trivial de instalar. (AirPlay fue un poco más difícil de configurar para mí.)
balu
8

¡Pavucontrol es el elemento que falta en este rompecabezas! También había configurado todo correctamente y el dispositivo externo (TV LG) mostraba que el sonido se estaba reproduciendo pero no escuché ningún sonido. Hoy instalé pavucontrol y cuando lo abrí encontré la opción de canalizar el sonido a través del servidor DLNA. La opción DLNA solo se muestra cuando hay salida de sonido de un reproductor a pulseaudio. ingrese la descripción de la imagen aquí

jumbli
fuente
Gracias por compartir esto. ¿Cómo configuró el servidor DLNA? Para mí, el cajero automático Rygel renuncia con segfaults bastante inútiles.
Takkat
Solo tengo configuraciones normales. Seguí el mismo enlace que mencionaste en tu publicación. [GstLaunch] enabled = true launch-items = audiotestsrc; audiotestsrc-title = ¡Transmisión en vivo de escritorio! audiotestsrc-mime = audio / mpeg audiotestsrc-launch = pulsesrc device = upnp.monitor! objetivo lamemp3enc = calidad calidad = 6
jumbli
Extraño. Con Rhythmbox, los valores predeterminados han desaparecido, pero todavía solo obtengo Invalid seek requestde Rygel. Los directorios de medios están ahí, pero mi flujo GST siempre es EOF.
Takkat
¡Además, te permite configurar un receptor para cada aplicación que puede reproducir audio! Puedo escuchar música en mi estéreo grande y guardar videos o sonidos de juegos en mi computadora. ¡Gracias!
cargado
¡Esto resolvió mi problema cuando todo estaba conectado y jugando pero solo faltaba el sonido!
easwee
4

Lo siento, no puedo ayudarte con Rygel, pero puede haber una alternativa que te funcione.

El principio es obtener un programa para grabar la secuencia en un archivo de audio, luego iniciar miniDLNA con una configuración personalizada que apunta al directorio en el que se encuentra la secuencia.

Ejemplo: supongamos que estamos trabajando en ~ / stream /. Crear ~ / 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

Luego guarde la secuencia en un archivo de audio en ese directorio. Buscar en Google el "audio de la tarjeta de sonido de grabación FFmpeg" produjo este comando

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

pero no tuve mucha suerte con eso. Otra opción es vlc si tienes una GUI disponible y esto no funciona.

Luego, inicie miniDLNA en otra ventana de terminal:

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

Se debe localizar OutputStream.flac y luego sea accesible desde el dispositivo de red.

Con suerte, si aún no lo ha resuelto, le dará algunas ideas.

mtdevans
fuente
1
Enfoque prometedor, gracias, pero necesita un mayor refinamiento. Con una prueba rápida con miniDLNA hoy, mi cliente DLNA no pudo reconocer el archivo continuo. Además, las corrientes producidas por ffmpeg parecen ser bastante pobres (ruido estático). Estoy en eso y te dejo saber.
Takkat
Hasta ahora, podemos generar un archivo de audio flac o mp3 desde el receptor de audio con ffmpeg o avconv. Sin embargo, miniDLNA no reconocerá este archivo a menos que dejemos de grabar. Luego, podemos abrir este archivo nuevamente en el cliente DLNA mientras grabamos otra instancia, pero la transmisión siempre comienza desde el comienzo de la grabación y se detiene en el momento en que comenzamos a escuchar en el cliente. ¿Alguna idea de cómo superar esto?
Takkat
Entonces, ¿quiere decir que una vez que ha interrumpido el proceso ffmpeg para detener la grabación, solo entonces miniDLNA reconoce el archivo? Además, ¿la calidad de audio es mejor? Lo probaré en mi máquina y veré si puedo hacerlo funcionar nuevamente. (Tuve algo similar trabajando el año pasado para transcodificar películas sobre la marcha)
mtdevans
Sí en primer lugar La segunda vez puedo acceder desde el cliente, pero comienza desde el principio (es decir, cada vez que comencé a grabar) y se detiene en el medio (es decir, después del tiempo exacto entre el inicio de la grabación y el inicio en el cliente). El audio está bien ahora, tuvo que desactivar el dúplex.
Takkat
4

Una idea que tuve que transmitir "lo que escucho" a un renderizador DLNA (como WDTV) fue hacer un servidor de la transmisión con VLC como transmisión http con pulse://alsa_output.xxx.monitorentrada y transcodificarla a MP3 o FLAC. Luego, quería usar algún punto de control de DLNA para permitir que el renderizador reproduzca la transmisión. VLC sirve el flujo transcodificado correctamente, pero no permite establecer el tipo mime, por lo que el procesador se niega a reproducirlo.

La siguiente idea fue escribir un servidor http en python que sirva la transmisión en su lugar. Obtiene el flujo de audio de pulse con parec, lo codifica con flac( lameo lo que desee) y establece el tipo de mimo correctamente.

Funciona con el siguiente script (muy simple):

#!/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()

Ajuste los parámetros, ejecútelos y apunte el procesador DLNA a su máquina. Funcionó para mí con un WDTV como procesador y un teléfono Android con BubbleUPnP como punto de control (puede escribir la URL de la transmisión al agregar un nuevo elemento a la lista de reproducción manualmente). Pero debería funcionar con cualquier dispositivo compatible con DLNA.

Adán
fuente
4

NOTA: Esta solución funciona, pero Massimo ha propuesto una solución más nueva y probablemente mejor .

Aquí hay una respuesta para Ubuntu 14.04 (también probado y trabajando en 15.04 ), para completar:

  1. instale los paquetes necesarios: sudo apt-get install rygel rygel-preferences rygel-gst-launch

  2. cree el archivo ~/.config/rygel.confque contiene lo siguiente:

    [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. Ejecute los siguientes comandos desde la línea de comandos (estos se pueden poner en un script si lo desea):

    pactl load-module module-http-protocol-tcp
    pactl load-module module-rygel-media-server 
    rygel &
    
  4. Ejecute el paprefscomando y asegúrese de que ambas opciones DLNA estén habilitadas (marcadas) en la pestaña "Servidor de red".

  5. Reproduce algo de audio en tu computadora. Ejecute el pavucontrolprograma y, en la pestaña "Reproducción", cambie el dispositivo de salida a "Streaming DLNA / UPnP".

En este punto, debería poder reproducir las transmisiones MPEG y FLAC desde un cliente DLNA (procesador / punto de control).

NOTA: es posible que deba reiniciar su computadora (o reiniciar el pulso) para que las cosas comiencen a funcionar.

marca
fuente
3

El script de Python de Adam es justo lo que necesitaba. Brillante. Rygel con gst-launch no funciona con uno de mis renderizadores, pero este script funciona con ambos. En mi caso, tomo una entrada de transmisión de audio de squeezelite (para squeezebox) y la envío a un renderizador. El script también funciona en la forma original para recibir información de un monitor de pulseaudio si eso es lo que se necesita.

Sabiendo poco sobre esto, logré hacer algunas adiciones al script que:

i) permitir que se ejecute desde un script de shell y terminar con un SIGTERM / SIGKILL (la declaración 'except' ahora incluye 'systemexit')

ii) permite que la secuencia de comandos se detenga y se reinicie y vuelva a usar el mismo puerto (ya que era la secuencia de comandos reiniciada tendía a fallar diciendo que no podía abrir el puerto si el procesador aún lo tenía abierto) - (allow_reuse_address = Declaración verdadera)

iii) cree una versión que tome la entrada de stdin y la muestree usando sox para generar en formato wav (en el puerto 8082)

Entonces mi versión se ve así:

#!/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()
pastim
fuente
1
He encontrado algunos problemas menores con este script.
pastim
@ Adam - Después de varias pruebas encontré algunos problemas menores con este programa. Sin embargo, el mayor problema es que la transmisión se detiene con el error 32 (tubería rota) después de un tiempo que está en proporción directa con la cantidad de datos enviados. Para una transmisión de calidad 24/96000, esto es poco más de una hora. En 24/192000 son poco más de 30 minutos. Para calidad de CD algo más de 3 horas. Al seleccionar la secuencia nuevamente en el renderizador, la secuencia comienza nuevamente. Creo que la solución puede ser 'codificación fragmentada'. Me preguntaba si alguien ha producido una versión fragmentada.
pastim
1

No estoy seguro de si esto será útil para usted ahora, pero escribí una publicación sobre cómo hacer que esto funcione en Ubuntu 12.10:

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

dpc.pw
fuente
Gracias por compartir esto, es exactamente lo que hasta ahora siempre ha fallado conmigo. Desde el diseño de este sitio, nos gustaría alentarlo a que describa los pasos que siguió (además de simplemente publicar el enlace en su blog) porque los enlaces pueden desaparecer con el tiempo y dejar su respuesta inútil. Me pondré en contacto con usted tan pronto como pueda probar esto.
Takkat
Aquí están mis observaciones hasta ahora: Seguir su guía bloquea a Rygel con SEGFAULT cuando selecciona la transmisión de audio del cliente en 12.04. En 12.10 no podemos crear una transmisión con GST-Launch. ¿Algo falta?
Takkat
La pregunta era sobre 12.04 y esta respuesta es para Ubuntu 12.10, de lo contrario lo votaría. :)
jdthood
Persona del futuro aquí: ese enlace se ha podrido. : P
datashaman