Existe-t-il un moyen de diffuser la sortie en direct de la carte son de notre ordinateur de bureau 12.04.1 LTS AMD64 sur un périphérique externe compatible DLNA de notre réseau? La sélection de contenu multimédia dans des répertoires partagés à l'aide de Rygel, miniDLNA et uShare est toujours acceptable - mais jusqu'à présent, nous n'avons pas réussi à obtenir un flux audio en direct vers un client via DLNA.
Pulseaudio prétend avoir un serveur multimédia DLNA/UPnP qui, avec Rygel, est censé faire exactement cela. Mais nous n'avons pas réussi à le faire fonctionner.
Nous avons suivi les étapes décrites dans live.gnome.org , cette réponse ici, ainsi que dans un autre guide similaire .
Dans 12.04 LTS , vous pouvez sélectionner le périphérique audio local ou notre flux GST-Launch dans le client DLNA, mais Rygel affiche le message suivant et le client l'indique. atteint la fin de la playlist:
(rygel:7380): Rygel-WARNING **: rygel-http-request.vala:97: Invalid seek request
Il n'y avait aucun moyen d'écouter des flux audio en direct sur le client.
Ce n’est qu’après une mise à niveau de la distribution vers 14.04 LTS que nous avons pu sélectionner un flux en direct sur nos rendus DLNA à partir de paramètres bien indiqué dans la réponse ci-dessous . Néanmoins, nous devions sélectionner un flux établi après avoir lancé rygel et ne pas être en mesure d'envoyer un nouveau flux à nos périphériques UPnP. Les métadonnées audio n'ont pas été transmises.
Existe-t-il d'autres solutions pour envoyer le son de notre carte son sous forme de diffusion en direct à un client DLNA?
J'ai créé un petit serveur qui découvre tous les moteurs de rendu upnp de votre réseau et les ajoute sous forme de puits à pulseaudio. Ainsi, vous pouvez contrôler chaque application via pavucontrol pour jouer sur vos appareils upnp.
C’est le genre de confort que j’ai toujours souhaité pour les appareils upnp sous linux.
L'application peut être installée depuis le paquet source ou DEB téléchargeable depuis git , ou après avoir ajouté le document officiel du projet ppa: qos/pulseaudio-dlna à nos sources avec:
Sudo apt-get update && Sudo apt-get install pulseaudio-dlna
Nous exécutons ensuite pulseaudio-dlna à partir de la ligne de commande avec les options suivantes:
pulseaudio-dlna [--Host <Host>] [--port <port>] [--encoder <encoder>] [--renderer-urls <urls>] [--debug]
pulseaudio-dlna [-h | --help | --version]
Voir aussi le pulseaudio-dlna "About" pour plus d'informations.
Lorsqu'un rendu DLNA était présent, vous pouvez le sélectionner dans le menu Son en tant que récepteur de sortie:
Pavucontrol est l’élément manquant de ce puzzle! J'avais également tout configuré correctement et le périphérique externe (téléviseur LG) indiquait que le son était en cours de lecture, mais je n'ai entendu aucun son. Aujourd'hui, j'ai installé pavucontrol et, lorsque je l'ai ouvert, j'ai trouvé l'option de canaliser le son via le serveur DLNA. L’option DLNA n’est affichée que lorsqu’un son est reproduit par pulseaudio.
Une des idées que je devais diffuser "ce que j’entendais" vers un moteur de rendu DLNA (comme WDTV) était de servir le flux avec VLC en tant que flux http avec Pulse://alsa_output.xxx.monitor
en entrée et de le transcoder au format MP3 ou FLAC. Ensuite, je voulais utiliser un point de contrôle DLNA pour laisser le moteur de rendu lire le flux. VLC sert correctement le flux transcodé, mais il ne permet pas de définir le type mime, de sorte que le moteur de rendu refuse de le lire.
L'idée suivante était d'écrire un serveur http dans python qui sert plutôt le flux. Il obtient le flux audio de Pulse avec parec
, le code avec flac
(ou lame
ou tout ce que vous voulez) et définit correctement le type mime.
Cela fonctionne avec le script suivant (très 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()
Ajustez les paramètres, exécutez-le et pointez le moteur de rendu DLNA sur votre machine. Cela fonctionnait pour moi avec un WDTV en tant que moteur de rendu et un téléphone Android avec BubbleUPnP en tant que point de contrôle (vous pouvez taper l'URL du flux lorsque vous ajoutez manuellement un nouvel élément à la liste de lecture). Mais cela devrait fonctionner avec tous les périphériques compatibles DLNA.
Je suis désolé de ne pouvoir vous aider du tout avec Rygel, mais il existe peut-être une alternative qui pourrait fonctionner pour vous.
Le principe est d'obtenir un programme pour enregistrer le flux dans un fichier audio, puis lancer miniDLNA avec une configuration personnalisée qui pointe vers le répertoire dans lequel se trouve le flux.
Exemple: Disons que nous travaillons dans ~/stream /. Créer ~/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
Enregistrez ensuite le flux dans un fichier audio de ce répertoire. Googler pour "FFmpeg record sound card sound" a donné cette commande
ffmpeg -f alsa -i default -acodec flac ~/stream/OutputStream.flac
mais je n'ai pas eu beaucoup de chance avec ça. Une autre option est vlc si vous avez une interface graphique disponible et cela ne fonctionne pas.
Ensuite, démarrez miniDLNA dans une autre fenêtre de terminal:
minidlna -d -f ~/stream/minidlna.conf -P ~/stream/minidlna.pid
Il devrait localiser OutputStream.flac et être ensuite accessible à partir de votre périphérique réseau.
Espérons que si vous ne l'avez pas déjà résolu, cela vous donnera quelques idées.
REMARQUE: cette solution fonctionne, mais une solution plus récente et probablement meilleure a été proposée par Massimo.
Voici une réponse pour Ubuntu 14.04 (également testé et fonctionnant sur 15.04 ) , pour être complet:
installer tous les paquets nécessaires: Sudo apt-get install rygel rygel-preferences rygel-gst-launch
créez le fichier ~/.config/rygel.conf
qui contient les éléments suivants:
[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=
Exécutez les commandes suivantes à partir de la ligne de commande (vous pouvez les insérer dans un script si vous le souhaitez):
pactl load-module module-http-protocol-tcp
pactl load-module module-rygel-media-server
rygel &
Exécutez la commande paprefs
et assurez-vous que les deux options DLNA sont activées (cochées) dans l'onglet "Serveur réseau".
Jouez de l'audio sur votre ordinateur. Exécutez le programme pavucontrol
et, dans l'onglet "Lecture", remplacez le périphérique de sortie par "DLNA/UPnP Streaming".
À ce stade, vous devriez pouvoir lire les flux MPEG et FLAC à partir d’un client DLNA (convertisseur de rendu/point de contrôle).
REMARQUE: vous devrez peut-être redémarrer votre ordinateur (ou redémarrer Pulse) pour que tout commence à fonctionner.
Le script python d'Adam est exactement ce dont j'avais besoin. Brillant. Rygel avec gst-launch ne fonctionne pas avec l'un de mes moteurs de rendu, mais ce script fonctionne avec les deux. Dans mon cas, je prends une entrée de flux audio de squeezelite (pour squeezebox) et l’envoie à un moteur de rendu. Le script fonctionne également dans sa forme originale pour prendre les entrées d’un moniteur pulseaudio si c’est ce qui est nécessaire.
En connaissant peu de tout cela, j'ai réussi à ajouter quelques éléments au script qui:
i) autoriser son exécution depuis un script shell et se terminer par un SIGTERM/SIGKILL (la déclaration "sauf" inclut désormais "systemexit")
ii) permet d'arrêter le script, de le redémarrer et de réutiliser le même port (comme c'était le cas du script redémarré qui avait tendance à échouer en indiquant qu'il ne pouvait pas ouvrir le port s'il était toujours ouvert) - (l'instruction allow_reuse_address = True)
iii) créer une version qui prend une entrée de stdin et la ré-échantillonne en utilisant sox pour une sortie au format wav (sur le port 8082)
Donc, ma version ressemble à:
#!/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()
Je ne sais pas si cela vous sera utile maintenant, mais j’ai écrit dans un post sur comment le faire fonctionner sur Ubuntu 12.10:
http://dpc.ucore.info/blog/2012/11/07/dlna-streaming-in-ubuntu-12-dot-10/