Como configurar fluxos de áudio ao vivo em um dispositivo compatível com DLNA?

54

Existe uma maneira de transmitir a saída ao vivo da placa de som do nosso desktop 12.04.1 LTS amd64 para um dispositivo externo compatível com DLNA em nossa rede? Selecionar conteúdo de mídia em diretórios compartilhados usando Rygel, miniDLNA e uShare é sempre bom - mas até agora não conseguimos obter um fluxo de áudio ao vivo para um cliente via DLNA.

A Pulseaudio afirma ter um servidor de mídia DLNA / UPnP que, juntamente com a Rygel, deve fazer exatamente isso. Mas não conseguimos fazê-lo funcionar.

Seguimos as etapas descritas em live.gnome.org , esta resposta aqui e também em outro guia semelhante .


No 12.04 LTS , podemos selecionar o dispositivo de áudio local ou nosso fluxo GST-Launch no cliente DLNA, mas Rygel exibe a seguinte mensagem e o cliente declara que chegou ao final da lista de reprodução:

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

Não havia como ouvir fluxos de áudio ao vivo no cliente.


Somente após uma atualização de distribuição para 14.04 LTS , pudemos selecionar uma transmissão ao vivo em nossos renderizadores DLNA a partir das configurações bem descritas na resposta abaixo . Ainda assim, precisamos selecionar um fluxo estabelecido depois que começamos o rygel e não conseguimos enviar um novo fluxo aos nossos dispositivos UPnP. Os metadados de áudio não foram transmitidos.


Existem outras alternativas para enviar o áudio da nossa placa de som como transmissão ao vivo para um cliente DLNA?

Takkat
fonte
Você pode evitar o fluxo DLNA com o seu dispositivo receptor? Minha solução é passar o fluxo pulseaudio por HTTP, veja mais aqui: sandalov.org/blog/1441 #
DmitrySandalov
Desculpe, não, eu realmente quero que o DLNA funcione porque o DLNA é amplamente implementado em vários clientes (TVs, receptores AV, players Blueray, etc.).
Takkat 31/10/12
Takkat, a solução da qual estou falando resolveu o problema de transmitir para o meu AVR. Se você realmente deseja iniciar um servidor DLNA, tive uma experiência positiva com o rygel + pulseaudio na 12.04 (após 'pacmd módulo de carga módulo-http-protocolo-tcp'), na 12.10 recebi os mesmos avisos 'Solicitação de solicitação inválida' .
DmitrySandalov
@DmitrySandalov: seria muito legal se você compartilhasse detalhes de como conseguiu configurar o Rygel para transmitir ao vivo a saída de áudio pulsado.
Takkat

Respostas:

63

Pulseaudio-DLNA

Criei um pequeno servidor que descobre todos os renderizadores upnp na sua rede e os adiciona como sumidouros ao pulseaudio. Assim, você pode controlar todos os aplicativos via pavucontrol para reproduzir em seus dispositivos upnp.

Esse é o tipo de conforto que eu sempre quis ao lidar com dispositivos upnp no linux.

O aplicativo pode ser instalado a partir da fonte ou do pacote DEB disponível para download no git , ou após adicionarmos o ppa: qos / pulseaudio-dlna oficial do projeto às nossas fontes com:

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

Em seguida, executamos o pulseaudio-dlna na linha de comando com as seguintes opções:

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

Veja também o pulseaudio-dlna "About" para mais.

Quando havia um renderizador DLNA presente, podemos selecioná-lo no menu de som como um coletor de saída:

insira a descrição da imagem aqui

Massimo
fonte
3
Ótima aplicação - obrigado! Funcionou bem em meus dispositivos, incluindo uma Samsung Smart TV (UE40ES6100). Apenas uma observação: também precisávamos python-requestscomo dependência e poderíamos selecionar o renderizador a partir dos controles de áudio padrão - sem a necessidade de instalar o pavucontrol.
Takkat 5/15
Estou feliz por ter gostado. Acabei de atualizar o README. Obrigado pela dica!
Massimo
2
Ótima solução. Obrigado. Mas eu tenho uma pergunta: há um atraso na reprodução de vários segundos (10 segundos após pressionar pausa no VLC). Esse é um "recurso" do DLNA ou existe alguma maneira de reduzi-lo? Então DLNA não faz sentido para reprodução de vídeo ou jogos? :(
JPT
2
O atraso vem do preenchimento do buffer HTTP. Ele mantém o fluxo em execução, caso sua conexão tenha problemas (wifi fraco, etc.). Se você deseja reduzir o atraso, use um codec que precise de muita largura de banda ( wav ) para preencher esse buffer mais rapidamente. A conexão por cabo sempre ajuda. Caso contrário, isso é muito específico para a implementação do firmware do fabricante. Por exemplo, eu tenho um atraso com Cocy cerca de 1 segundo. Sonos Toque 1 com wav: 1 segundo, com mp3: 5 segundos. Tudo conectado via cabo. Mas você não vai se livrar completamente disso. O principal objetivo são os livros de música e áudio. Tudo o que não precisa estar sincronizado.
Massimo
11
@JPT e todo mundo procurando uma maneira de corrigir o atraso (10s para mim): Usando o shairport-sync , estou executando um coletor AirPlay no meu RaspberryPi em paralelo ao coletor DLNA e devo dizer que os atrasos são muito mais curtos (~ 2s para iniciar; a parada é imediata). Dito isto, muito obrigado a Massimo porque, esquecendo o atraso, o pulseaudio-dlna funciona como um encanto e é realmente fácil de instalar! (AirPlay foi um pouco mais difícil de configurar para mim.)
balu
8

Pavucontrol é o item que falta neste quebra-cabeça! Eu também havia configurado tudo corretamente e o dispositivo externo (LG TV) estava mostrando que o som estava sendo reproduzido, mas não ouvi nenhum som. Hoje instalei o pavucontrol e, quando o abri, encontrei a opção de canalizar o som através do servidor DLNA. A opção DLNA é mostrada apenas quando há saída de som de um player para o pulseaudio. insira a descrição da imagem aqui

jumbli
fonte
Obrigado por compartilhar isso. Como você configurou o servidor DLNA? Para mim, o ATM Rygel sai com segfaults bastante inúteis.
21412 Takkat
Eu tenho apenas configurações normais. Eu segui o mesmo link que você mencionou em sua postagem. [GstLaunch] enabled = true launch-items = audiotestsrc; audiotestsrc-title = Desktop Live Streaming! audiotestsrc-mime = audio / mpeg audiotestsrc-launch = pulsesrc device = upnp.monitor! destino lamemp3enc = qualidade qualidade = 6
jumbli
Esquisito. Com o Rhythmbox, as segfaults desapareceram, mas eu ainda só recebo o Invalid seek requestRygel. Os diretórios de mídia estão lá, mas meu fluxo GST é sempre EOF.
22412 Takkat
Além disso, permite definir um coletor para cada aplicativo que pode reproduzir áudio! Posso ouvir música no meu aparelho de som grande e manter vídeos ou sons de jogos no meu computador. Obrigado!
springloaded
Isso resolveu meu problema quando tudo estava conectado e em execução, mas faltava apenas som!
easwee 4/07
4

Sinto muito, mas não posso ajudá-lo com Rygel, mas pode haver uma alternativa que funcione para você.

O princípio é obter um programa para gravar o fluxo em um audiofile e iniciar o miniDLNA com uma configuração personalizada que aponte para o diretório em que o fluxo está.

Exemplo: digamos que estamos trabalhando em ~ / stream /. Crie ~ / 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

Em seguida, salve o fluxo em um audiofile nesse diretório. A pesquisa no Google "Áudio da placa de som de gravação FFmpeg" produziu este comando

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

mas não tive muita sorte com isso. Outra opção é vlc: você tem uma interface gráfica disponível e isso não funciona.

Em seguida, inicialize o miniDLNA em outra janela do terminal:

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

Ele deve localizar OutputStream.flac e, em seguida, ser acessível a partir do seu dispositivo de rede.

Espero que, se você ainda não o resolveu, isso lhe deu algumas idéias.

mtdevans
fonte
11
Abordagem promissora - obrigado -, mas precisa de mais refinamentos. Hoje, com um teste rápido com o miniDLNA, não consegui obter o arquivo de fluxo reconhecido pelo meu cliente DLNA. Além disso, os fluxos produzidos pelo ffmpeg parecem bastante ruins (ruído estático). Estou nisso e deixo você saber.
Takkat 16/10/12
Até agora, somos capazes de gerar um arquivo de áudio flac ou mp3 a partir do coletor de áudio com ffmpeg ou avconv. No entanto, esse arquivo não será reconhecido pelo miniDLNA, a menos que paremos de gravar. Depois, podemos abrir esse arquivo novamente no cliente DLNA durante a gravação de outra instância, mas o fluxo sempre começa no início da gravação e para no momento em que começamos a ouvir no cliente. Alguma idéia de como superar isso?
Takkat 27/10/12
Então, como você interrompeu o processo ffmpeg para interromper a gravação, só então o arquivo é reconhecido pelo miniDLNA? Além disso, a qualidade do áudio é melhor? Vou testá-lo na minha máquina e ver se consigo fazê-lo novamente. (Eu tinha algo de trabalho semelhante no ano passado para a transcodificação de filmes on the fly)
mtdevans
Sim em primeiro lugar. Na segunda vez, posso acessá-lo pelo cliente, mas ele começa do início (ou seja, sempre que comecei a gravar) e para no meio (ou seja, após exatamente o tempo entre o início da gravação e o recebimento no cliente). O áudio está bom agora, tive que desativar o duplex.
Takkat 27/10/12
4

Uma idéia que tive que transmitir "o que ouvi" a um renderizador DLNA (como WDTV) foi o servidor de fluxo com VLC como fluxo http com pulse://alsa_output.xxx.monitorentrada e transcodificado para MP3 ou FLAC. Então eu queria usar algum ponto de controle DLNA para deixar o renderizador reproduzir o fluxo. O VLC atende ao fluxo transcodificado corretamente, mas não permite definir o tipo MIME; portanto, o renderizador se recusa a reproduzi-lo.

A próxima idéia foi escrever um servidor http em python que serve o fluxo. Ele recebe o fluxo de áudio do pulso parec, codifica-o flac( lameou o que você quiser) e define o tipo de mímica corretamente.

Funciona com o seguinte script (muito simples):

#!/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 os parâmetros, execute-o e aponte o renderizador DLNA para sua máquina. Funcionou para mim com um WDTV como renderizador e um telefone Android com BubbleUPnP como ponto de controle (você pode digitar o URL do fluxo ao adicionar um novo item à lista de reprodução manualmente). Mas deve funcionar com qualquer dispositivo compatível com DLNA.

Adão
fonte
4

NOTA: Esta solução funciona, mas uma solução mais nova e provavelmente melhor foi proposta pela Massimo.

Aqui está uma resposta para o Ubuntu 14.04 (também testado e funcionando no 15.04 ), para ser completo:

  1. instale os pacotes necessários: sudo apt-get install rygel rygel-preferences rygel-gst-launch

  2. crie o arquivo ~/.config/rygel.confque contém o seguinte:

    [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. Execute os seguintes comandos na linha de comando (eles podem ser colocados em um script, se desejado):

    pactl load-module module-http-protocol-tcp
    pactl load-module module-rygel-media-server 
    rygel &
    
  4. Execute o paprefscomando e verifique se as duas opções de DLNA estão ativadas (marcadas) na guia "Servidor de rede".

  5. Reproduza um pouco de áudio no seu computador. Execute o pavucontrolprograma e, na guia "Reprodução", altere o dispositivo de saída para "DLNA / UPnP Streaming".

Nesse ponto, você poderá reproduzir os fluxos MPEG e FLAC de um cliente DLNA (renderizador / ponto de controle).

NOTA: pode ser necessário reiniciar o computador (ou reiniciar o pulso) para que as coisas comecem a funcionar.

Marca
fonte
3

O script python de Adam é exatamente o que eu precisava. Brilhante. O Rygel com gst-launch não funciona com um dos meus renderizadores, mas esse script funciona com ambos. No meu caso, estou pegando uma entrada de fluxo de áudio do squeezelite (para squeezebox) e enviando para um renderizador. O script também funciona na forma original para receber informações de um monitor pulseaudio, se for necessário.

Sabendo pouco sobre isso, consegui fazer algumas adições ao script que:

i) permitir que seja executado a partir de um script shell e finalizado com um SIGTERM / SIGKILL (a instrução 'exceto' agora inclui 'systemexit')

ii) permite que o script seja parado e reiniciado e reutilize a mesma porta (como o script reiniciado tendia a falhar, dizendo que não seria possível abrir a porta se o renderizador ainda a abrisse) - (a instrução allow_reuse_address = True)

iii) crie uma versão que aceite a entrada do stdin e a faça uma nova amostragem usando sox para gerar no formato wav (na porta 8082)

Então, minha versão se parece com:

#!/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
fonte
11
Eu encontrei alguns problemas menores com este script.
pastim 9/06/14
@ Adam - Após vários testes, encontrei alguns problemas menores com este programa. No entanto, o maior problema é que o streaming para com o erro 32 (canal quebrado) após um tempo proporcional à quantidade de dados enviados. Para um fluxo de qualidade 24/96000, isso é pouco mais de uma hora. Em 24/192000, são pouco mais de 30 minutos. Para qualidade de CD um pouco mais de 3 horas. Ao selecionar o fluxo novamente no renderizador, o fluxo inicia novamente. Acredito que a solução pode ser 'codificação em blocos'. Gostaria de saber se alguém produziu uma versão em pedaços.
pastim
1

Não tenho certeza se isso será útil para você agora, mas escrevi um post sobre como fazer isso funcionar no Ubuntu 12.10:

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

dpc.pw
fonte
Obrigado por compartilhar isso - é exatamente o que até agora sempre falhava comigo. No design deste site, gostaríamos de encorajá-lo a descrever as etapas que você seguiu (além de apenas postar o link no seu blog), pois os links podem desaparecer com o tempo, deixando sua resposta inútil. Voltarei a você assim que puder testar isso.
Takkat
Aqui estão minhas observações até agora: O seguinte guia trava o Rygel com o SEGFAULT ao selecionar o fluxo de áudio do cliente na versão 12.04. Na versão 12.10, não podemos criar um fluxo com o GST-Launch. Falta alguma coisa?
Takkat 8/11
A pergunta era sobre 12.04 e esta resposta é para o Ubuntu 12.10, caso contrário, eu votaria. :)
jdthood
Pessoa do futuro aqui: esse link apodreceu. : P
datashaman 14/08/2015