Multiroom avec budget Snapcast

La création de systèmes audio multi-pièces permet d'atteindre plusieurs objectifs à la fois.



  1. Lecture du même signal audio dans plusieurs pièces (musique de fond)
  2. La possibilité de reproduire son propre signal audio dans chaque pièce
  3. Possibilité de lecture distribuée des notifications (par exemple, la sonnette ne sonne pas près de la porte à plein volume, mais à faible volume via tout ou via certains haut-parleurs).


Dans cet article, je vais partager un exemple de construction d'un système multi-pièces dans mon propre appartement. L'idée originale était de créer une musique de fond (la station de radio sélectionnée) à faible volume dans toutes les pièces, au lieu d'un point où le volume devait être augmenté.



La base du système multi-room était la solution gratuite Snapcast . La partie serveur est lancée sur le serveur domestique; soit des mini-ordinateurs Orange PI zero avec des haut-parleurs actifs connectés, soit des Rasberry PI plus puissants avec un lecteur multimédia Kodi installé (distributeur Libreelec) agissent en tant que clients par pièce.



Principales caractéristiques du système fini



  1. Lecture d'une station de radio Internet en arrière-plan
  2. La possibilité de lire de la musique sur un multi-room (ou sur un client sélectionné séparément) en utilisant Airplay, UPnP ou via un lecteur Plex. Il est prévu d'ajouter le support Bluetooth, bien que cela ne me concerne pas particulièrement
  3. Lecture de contenu arbitraire à partir d'un ordinateur via une interface Web
  4. Changement de la station de radio en cours de lecture manuellement ou selon l'horaire
  5. Affectation à chaque client de n'importe quelle source
  6. Le contrôle du volume est individuellement pour chaque périphérique audio (cela fonctionne comme ceci: le contrôle du système audio est réglé au maximum, le volume de chaque snapclient est ajusté à partir du serveur si nécessaire (généralement également réglé au maximum), et le niveau de volume global est ajusté à partir de la source à partir de laquelle la lecture est effectuée - le téléphone , lecteur informatique ou mpd)


Les clients sont maintenant faits sans fioritures - il y a armbian, sur lequel shairport et snapclient sont installés, et il est prévu de fournir upmpdcli et plexamp, de sorte que chaque client agisse comme un point universel qui reproduit le son en utilisant n'importe quel protocole possible. Le principal problème qui empêche toujours cela d'être fait est que Linux ne permet pas de partager un périphérique audio ALSA entre plusieurs programmes, et ici vous devez soit en désactiver les autres tout en jouant du son via un service, soit essayer d'utiliser Pulseaudio, ce qui est impossible dans le cas de Snapclient (Snapcast fonctionne exclusivement via ALSA, car il minimise les retards et de ce fait le son de toutes les sources est absolument synchrone (plus de détails peuvent être trouvés dans la documentation Snapcast).



Le côté serveur est conçu comme des microservices sous la forme de plusieurs conteneurs docker combinés en une pile. Au départ, il était prévu de lancer des conteneurs dans le cluster Swarm (oui, j'ai deux ordinateurs à la maison combinés dans un cluster Swarm, qui exécute tous les services dont j'ai besoin et dont je n'ai pas vraiment besoin à la maison), mais cette idée a dû être abandonnée, et la pile via docker-compose Le fichier .yml est exécuté sur l'un des ordinateurs. La fiabilité est bien sûr boiteuse, mais suffisante pour la maison. La raison de l'impossibilité de démarrer dans le cluster est que le serveur Snapcast utilise fifo pour recevoir le flux audio (une chaîne typique fonctionne comme ceci - le son est joué en utilisant mpd, le fifo est le périphérique de sortie, à partir duquel le snapserver lit et transmet le flux à tous les clients). Mais en raison du fait que le cluster ne peut pas partager de volume,qui héberge un fifo entre plusieurs nœuds (utiliser un fifo sur un hôte et le transmettre à l'aide d'un système de fichiers distribué ne fonctionne pas non plus. Bien que cela puisse être possible via nfs, je ne l'ai pas encore essayé), et il est également impossible de forcer le cluster swarm à exécuter tous les conteneurs sur un nœud, le seul moyen de donner accès à tous les services au fifo est de tout exécuter sur un seul nœud (vous pouvez, bien sûr, créer une machine virtuelle, ou un gigantesque conteneur, où tout est lancé via superviseur, mais j'ai décidé de ne pas le faire).la seule façon de donner accès à tous les services à la fifo est de tout exécuter sur un seul nœud (vous pouvez, bien sûr, créer une machine virtuelle, ou un gigantesque conteneur, où tout est lancé via le superviseur, mais j'ai décidé de ne pas le faire).la seule façon de donner accès à tous les services à la fifo est de tout exécuter sur un seul nœud (vous pouvez, bien sûr, créer une machine virtuelle, ou un gigantesque conteneur, où tout est lancé via le superviseur, mais j'ai décidé de ne pas le faire).



Composition de la pile



1) Snapserver. Conteneur de serveur Snapcast. Il est disponible sur les ports 1704, 1705 et dans le réseau domestique, ses appels passent par le nom DNS snapserver.local. Il sait comment s'annoncer via Avahi, mais lorsque vous travaillez dans avahi docker, les annonces passent par un conteneur séparé (il n'est pas inclus dans cette pile).



2) Snapcastr. Service Web Snapserver. Disponible sur le port 5011 (disponible en tant que snapcastr.local via un proxy inverse local).



3) Snapchanger. Script Python qui analyse les sources audio et fait basculer les clients vers la source audio la plus prioritaire actuellement active. Par exemple, la radio Internet a la priorité la plus basse et joue toujours. Lors de la lecture de musique à partir d'un téléphone via Airplay, il bascule sur ce flux, et si à ce moment il y a un signal d'une maison intelligente, il y passera. Lorsqu'un flux est arrêté, il revient aux flux actifs avec la priorité la plus élevée. Pour chaque client, vous pouvez spécifier votre liste de threads et leurs priorités.



4) Snapcron. Un conteneur avec cron qui peut exécuter des scripts à un certain moment, par exemple, changer le volume sur les clients (éteindre complètement la musique dans la chambre la nuit).



5) mpd. instance mpd pour écouter la radio Internet. Transféré vers le réseau domestique sur un port non standard 36602.



6) radio. des scripts pyhthon qui garantissent que la radio est toujours lue (il y a des cas où la connexion est interrompue, ou la connexion semble être là, mais le son ne joue pas), ainsi que la commutation des stations de radio et du volume en fonction de l'heure de la journée.



7-8) mpd.fm et pifi - coquilles Web pour écouter les stations de radio. Deux pièces du même type pour les expériences.



9) mopidy. Un autre shell (aka un serveur mpd séparé) pour jouer de la musique. Il agit comme un serveur mpd séparé et répond au port standard mpd - 6600. Peut être utilisé pour écouter de la musique. Il utilise son propre flux et fonctionne indépendamment de mpd pour les stations de radio.



10-12) shairport-sync, upmpdcli, plexamp - conteneurs avec les clients correspondants. Chacun des conteneurs utilise sa propre instance de mpd, écrivant dans sa propre fifo. Ainsi, chaque client a son propre flux indépendant.



Ainsi, la pile prend désormais en charge:



  • Plusieurs sources sonores indépendantes avec un choix arbitraire entre elles - Par défaut, uPnP, Mopidy, Plexamp, AirPlay et radio Internet.
  • Gérer le serveur Snapcast lui-même avec Snapcastr.
  • Un ensemble de scripts pour assurer un son de fond radio fiable et ininterrompu.
  • Contrôle de la lecture radio en utilisant pi-fi ou mpd.fm (en plus, j'ai configuré le contrôle de cette instance mpd en utilisant le Node-red utilisé dans ma domotique).


Lien vers le référentiel



All Articles