Résumé des épisodes précédents

  • Le streaming n'était pas le sujet de ce billet. Dans ma grande bonté, j'en refais donc un complet.


Comprenons-nous bien

  • Ce titre légèrement menaçant fait un peu vendeur de savonnettes dé-régulées cherchant à forcer l'entrée de votre habitation. Cette fois, il ne s'agit que d' une nécessaire introduction à ce qu'est réellement mpd.


De l'avantage du stream
  • Pourquoi écouter un stream , et ne pas décoder en local ?
    • Vous ne compilerez qu'une fois le player.
    • Vous ne dupliquez pas vos fichiers, vous n'avez pas besoin de les promener sur une clé usb ou un disque externe.
    • Vous allez faire l'envie de vos voisins (en général, cet argument suffit à emporter la décision).


mpd n'est pas forcément ce que l'on croit
  • mpd est un player dont la sortie sonore se fait en local par défaut (c'est à dire, sur la machine où mpd est lancé).
    • Les clients de mpd, tels que ncmpc ou gmpc (client Gnome) ne sont rien d'autre que des télécommandes pour mpd.
    • Aucun d'entre eux ne permet d'écouter un stream.
    • Ils ne savent qu'envoyer des commandes au daemon mpd.
  • Un client mpd est une télécommande ... donc cela signifie que seul le PC faisant tourner le serveur est en mesure de sortir du son, et que tous les clients associés à mpd ne servent qu'à contrôler celui-ci à distance ?
    • Exactement ! Je n'aurais su mieux le dire !


mais mpd peut streamer
  • Néanmoins, si les clients spécifiques à mpd ne peuvent que le contrôler, mpd est capable de différents rendus.
    • Les sorties locales, avec la configuration OSS , Alsa ou ... null (qui est bien un rendu local)
    • Des sorties streamées, avec entre autres un serveur shoutcast, ou son serveur interne httpd.
  • Nous allons utiliser le serveur intégré à mpd, qui streame sans fioritures, tel une web-radio.
  • Dès à présent, il est utile de préciser que nous allons utiliser deux ports.
    • Le port de commande de mpd, sur lequel nous pouvons connecter un client, ou lancer un telnet.
    • Le port utilisé par mpd pour servir le stream. Celui-ci n'est actif que quand de la musique est jouée. Il est fermé dès que la musique est stoppée.



Préparation et configuration de mpd

Flags de compilation Gentoo

media-sound/mpd -alsa -ffmpeg mikmod musepack ogg vorbis lame

  • Votre avis concernant ffmpeg pourra varier, mais j'ai préféré limiter les temps de compilation sur une machine un peu limitée.
  • J'ai bien sûr retiré toute référence à Alsa (OSS étant inactif par défaut), vu que la machine hébergeant le serveur n'a même pas de carte son.


PKGBUILD pour Arch

Arch a déja son paquet, qui contient un tas de dépendances qui vont faire exploser votre serveur.

Le mieux est de reprendre le PKGBUILD de ABS, pour obtenir les flags de la distribution, et de l'adapter.

Penser ensuite à bloquer les mises à jour de MPD dans pacman.conf.

Voici les deux modifications que j'ai apporté au PKGBUILD :

  • depends

J'ai viré tout un tas de trucs qu'il ne fallait surtout pas installer, car invasif (trop de dépendances), ou inutile (jack), ou les deux (pulse, ahaha!). J'ai enlevé libmodplug après quelques hésitations, et je l'ai remplacé par mikmod.

Je me suis également permis d'ajouter le support Ogg-Vorbis.


depends=('libmikmod' 'libmad' 'libid3tag' 'libogg' 'libvorbis')

Il ne reste vraiment pas grand monde, mais ça devrait suffire.


  • options de ./configure

Le massacre continue avec les options de configure. Hâtons nous de virer cet horrible systemd, lastfm et autres soundcloud. Bon, ça ira plus vite si je vous donne le nouveau.


  ./configure \n    --prefix=/usr \n    --sysconfdir=/etc \n    --enable-httpd-output \n    --enable-id3 \n    --enable-mikmod \n    --disable-oss \n    --enable-vorbis

La reconstitution du PKGBUILD est laissé à titre d'exercice au lecteur, je me suis contenté ici de donner ce qui changeait, plutôt que de vous noyer sous les inutiles détails de ce qui ne changeait pas.


Création des répertoires nécessaires
  • mpd peut être lancé par un utilisateur lambda.
    • Vous devriez mettre sa configuration dans le home de celui-ci, et ajuster le paramètre user dans le fichier de configuration.


Fichier de configuration

Voici mon fichier de configuration.

Je n'ai pas inclu tout ce qui ne sert pas, reportez vous au fichier /etc/mpd.conf pour plus de précisions.

Son nom et son emplacement dépend de l'utilisateur qui va lancer mpd.

  • root : /etc/mpd.conf
  • un utilisateur : /home/toto/.mpdconf

Pour vos essais, vous pouvez simplifier la situation en ne mettant pas de mot de passe, par exemple.


music_directory  "/home/toto/music"
playlist_directory  "/home/toto/mpd/playlists"
db_file  "/home/toto/mpd/database"
log_file  "/home/toto/mpd/mpd.log"
pid_file  "/home/toto/mpd/mpd.pid"
state_file  "/home/toto/mpd/state"

#ATTENTION : si vous ne lancez pas mpd en root, commentez «user»
#user  "toto"

bind_to_address  "0.0.0.0"
port  "1234"
password  "password@read,add,control,admin"
default_permissions  "" #pas de bras, pas de chocolat.

input {
        plugin "curl"
}

audio_output {
        type  "httpd"
       name  "My HTTP Stream"
        encoder  "lame"  # optional, vorbis or lame
        port  "5678"
        bitrate  "128"  # do not define if quality is defined
        format  "44100:16:1"
}
filesystem_charset "UTF-8"

  • bind_to_address : ne mettez surtout pas localhost ou 127.0.0.1 :
    • Cela provoquerait un bind de mpd sur l'interface loopback. Toute connexion externe serait alors impossible.
    • Cependant, vous pourrez toujours faire un tunnel ssh avec l'adresse "127.0.0.1"
    • A la place de 0.0.0.0 on peut mettre l'IP d'une carte réseau. Par exemple pour une machine directement sur le net (avec une IP publique) on veut pas forcément rendre mpd accessible. Alors qu'en mettant l'IP de la machine sur le LAN (disons 192.168.1.1) ça ne sera accessible que sur le réseau local.
  • default_permissions : pour vos essais en connexion anonyme (sans mot de passe), vous pouvez mettre les permissions à fond avec read,add,control,admin.
  • Pour pouvoir vous connecter si vous avez compilé mpd avec tcp_wrapper (libwrap) , vous devrez peut-être ajouter dans /etc/hosts.allow

mpd: ALL



Premier lancement

Placez quelques fichiers musicaux dans le répertoire définit comme music_directory dans le fichier de configuration.

Le premier lancement se fera en local, avec l'utilisateur configuré dans mpd.conf

Au passage, nous allons créer la base de données.

Par la suite, la commande update sera envoyée par un client mpd.

Dans les anciennes versions, il suffisait de faire ceci:


toto@serveur ~$ mpd --create-db

Hélas, cette méthode ne fonctionne plus, que l'on soit simple utilisateur ou root. Ne croyez pas la FAQ qui prétend que l'on peut créer la base avec l'utilisateur root. Dans tous les cas, vous aurez cette erreur:


/tmp# mpd --create-db

** (mpd:32740): CRITICAL **: option parsing failed: Unknown option --create-db

Alors que faire ?

D'autres sources conseillent de faire un mpc update, mais encore faudrait-il que mpd soit lancé. Or, mpd se plante au démarrage puisque la base de données n'est pas là.

Résistez également à la tentation de faire un touch pour créer la base à la main. Ça ne fonctionnera pas.

La seule chose que j'ai trouvé a été de créer une config minimale dans /etc/mpd.conf et de lancer mpd en tant que root. Ensuite, je l'ai tué et j'ai récupéré le fichier database.db à l'endroit où mpd l'avait créé (j'avais tout mis dans /tmp).

Alors pour info, il s'agit d'un stupide fichier texte. Le voici, si vous rencontrez les mêmes problèmes, un copier/coller pourrait vous faire gagner du temps.

Le dump après le cat vous donne le format binaire strict, au cas où vous auriez des problèmes avec votre éditeur (rappel: sous Unix, une fin de ligne est codée sur un seul octet: 0x0a).


/etc# cat /tmp/database.db 
info_begin
format: 1
mpd_version: 0.17.3
fs_charset: UTF-8
tag: Artist
tag: ArtistSort
tag: Album
tag: AlbumArtist
tag: AlbumArtistSort
tag: Title
tag: Track
tag: Name
tag: Genre
tag: Date
tag: Composer
tag: Performer
tag: Disc
tag: MUSICBRAINZ_ARTISTID
tag: MUSICBRAINZ_ALBUMID
tag: MUSICBRAINZ_ALBUMARTISTID
tag: MUSICBRAINZ_TRACKID
info_end

/etc# hexdump /tmp/database.db  -C
00000000  69 6e 66 6f 5f 62 65 67  69 6e 0a 66 6f 72 6d 61  |info_begin.forma|
00000010  74 3a 20 31 0a 6d 70 64  5f 76 65 72 73 69 6f 6e  |t: 1.mpd_version|
00000020  3a 20 30 2e 31 37 2e 33  0a 66 73 5f 63 68 61 72  |: 0.17.3.fs_char|
00000030  73 65 74 3a 20 55 54 46  2d 38 0a 74 61 67 3a 20  |set: UTF-8.tag: |
00000040  41 72 74 69 73 74 0a 74  61 67 3a 20 41 72 74 69  |Artist.tag: Arti|
00000050  73 74 53 6f 72 74 0a 74  61 67 3a 20 41 6c 62 75  |stSort.tag: Albu|
00000060  6d 0a 74 61 67 3a 20 41  6c 62 75 6d 41 72 74 69  |m.tag: AlbumArti|
00000070  73 74 0a 74 61 67 3a 20  41 6c 62 75 6d 41 72 74  |st.tag: AlbumArt|
00000080  69 73 74 53 6f 72 74 0a  74 61 67 3a 20 54 69 74  |istSort.tag: Tit|
00000090  6c 65 0a 74 61 67 3a 20  54 72 61 63 6b 0a 74 61  |le.tag: Track.ta|
000000a0  67 3a 20 4e 61 6d 65 0a  74 61 67 3a 20 47 65 6e  |g: Name.tag: Gen|
000000b0  72 65 0a 74 61 67 3a 20  44 61 74 65 0a 74 61 67  |re.tag: Date.tag|
000000c0  3a 20 43 6f 6d 70 6f 73  65 72 0a 74 61 67 3a 20  |: Composer.tag: |
000000d0  50 65 72 66 6f 72 6d 65  72 0a 74 61 67 3a 20 44  |Performer.tag: D|
000000e0  69 73 63 0a 74 61 67 3a  20 4d 55 53 49 43 42 52  |isc.tag: MUSICBR|
000000f0  41 49 4e 5a 5f 41 52 54  49 53 54 49 44 0a 74 61  |AINZ_ARTISTID.ta|
00000100  67 3a 20 4d 55 53 49 43  42 52 41 49 4e 5a 5f 41  |g: MUSICBRAINZ_A|
00000110  4c 42 55 4d 49 44 0a 74  61 67 3a 20 4d 55 53 49  |LBUMID.tag: MUSI|
00000120  43 42 52 41 49 4e 5a 5f  41 4c 42 55 4d 41 52 54  |CBRAINZ_ALBUMART|
00000130  49 53 54 49 44 0a 74 61  67 3a 20 4d 55 53 49 43  |ISTID.tag: MUSIC|
00000140  42 52 41 49 4e 5a 5f 54  52 41 43 4b 49 44 0a 69  |BRAINZ_TRACKID.i|
00000150  6e 66 6f 5f 65 6e 64 0a                           |nfo_end.|
00000158

  • En cas d'erreur, ou de modification de la base, vous pouvez tuer le serveur avec :
    • kill $(pidof mpd)
  • Par la suite, vous pourrez utiliser les scripts Gentoo (ou de votre distrib) pour demander le démarrage de mpd au boot.


Test rapide avec telnet
  • Plus qu'à tenter un telnet sur le port de votre serveur
  • Vous pouvez trouver toutes les commandes comprises par mpd ici:

toto@serveur ~/.ncmpc $ telnet localhost 1234
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
OK MPD 0.15.0
status
volume: -1
repeat: 0
random: 0
single: 0
consume: 0
playlist: 3
playlistlength: 0
xfade: 0
state: stop
OK
close
Connection closed by foreign host.

  • status vous permettra d'obtenir rapidement confirmation du fonctionnement de mpd.
    • Même si la simple réussite de la connexion telnet devrait suffire.
  • Pour fermer proprement la session, utilisez close.



mpc dépanne certes bien...

  • Maintenant que le daemon mpd fonctionne, il est temps de tester avec un logiciel un peu plus évolué, et à distance.
    • Je vous conseille de rester sur le réseau local de mpd, ceci limitera les ports à ouvrir dans le firewall, et vous pourrez toujours vous passer d'authentification.
  • L'informatique aime les acronymes, et les doublons aussi.
    • mpc = music player client
    • ne confondez pas avec les vieux fichiers musepack (extension mpc) que l'on peut jouer avec mpd.
  • mpc est un utilitaire indispensable pour vous éviter des telnet rapidement saoulants sur le port du daemon mpd.
  • Je vous laisse faire man mpc , le fonctionnement est trivial.


...mais ncmpc est toujours le plus beau

  • Maintenant que tout semble bien tourner, il est temps de passer au client qui ne nous quittera plus.
  • Avec un nom à coucher dehors, ncmpc est néanmoins le plus agréable des clients mpd.
  • Interprétation personnelle du nom:
    • nc = ncurses
    • mpc = music player client


Version dans Portage (avril 2010)
  • 0.14
    • un peu vieille, mais que voulez-vous ...
Flags Gentoo

media-sound/ncmpc artist-screen colors help-screen key-screen lyrics-screen search-screen song-screen

  • Beaucoup de possibilités dans les versions récentes de ncmpc , y compris la possibilité d'afficher les paroles des chansons.
    • J'ai activé toutes les options, ça ne mange pas de pain (ni de ressources).


Erreur possible à la compilation de ncmpc

match.c:43: attention : implicit declaration of function ‘g_regex_match_simple’
match.c:45: erreur: ‘G_REGEX_CASELESS’ undeclared (first use in this function)

  • Dans ce cas, il faut mettre à jour votre glib (pas la glibc , je parle bien de la glib tout court) et recommencer l'emerge de ncmpc.


Fichier de configuration de ncmpc
  • Il se trouve dans ~/ncmpc/config
  • Celui-ci est donné juste pour information. Je n'ai pas encore pris le temps de fignoler.

port = 1234
password = "password"
scroll = yes
scroll-sep = " ***** "
enable-colors = yes
color background = black
color list = brightwhite



Diagnostics

  • Lancez la lecture d'un fichier avec mpc, ncmpc, telnet, ou ce que vous voudrez.
    • Ceci doit produire l'envoi du stream sur le port défini pour httpd dans la configuration de mpd.
    • Le port stream ne sera ouvert que pendant la génération d'un stream.

toto@serveur ~$ netstat -pln | grep mpd
tcp        0      0 0.0.0.0:1234            0.0.0.0:*               LISTEN      3694/mpd
tcp        0      0 0.0.0.0:5678            0.0.0.0:*               LISTEN      3694/mpd

  • Les ports utilisés sont ceux définis dans mpd.conf
    • Le port de commande de mpd est 1234.
    • Le stream est joué sur 5678.



La config du pauvre, mais qui marche tellement bien

  • Et encore j'avais un titre plus long pour cette partie, mais il faut savoir rester raisonnable.
  • Nous allons utiliser un tunnel ssh dans lequel nous ferons passer le flux.
    • Ceci nous évitera de partager nos disques avec la terre entière, ce qui serait non seulement illégal, mais très consommateur en bande passante.


Tunnel ssh
  • Ce n'est pas le sujet de ce billet, je vous donne donc la commande pour créer un tunnel ssh.
    • Il y a pas mal d'explications à ce sujet un peu partout, les curieux devraient trouver leur compte facilement.
    • Sous MS-Windows, vous pouvez créer facilement des tunnels avec Putty.
  • pour créer un tunnel ssh entre votre machine et le serveur mpd

ssh -C -L 5678:localhost:5678 a.b.c.d

  • 5678 : port configuré sur mpd pour exporter le stream httpd (ce n'est pas le port de commande de mpd)
  • localhost : car vous allez vous connecter sur votre machine pour la redirection de port.
  • a.b.c.d : ip de la machine distante faisant tourner mpd.


  • En prime, vous récupérez un shell où vous pourrez lancer ncmpc pour controler mpd.


mpd
  • Exporte le flux httpd.
  • Les façons de le lancer ont été vues plus haut:
    • en user : mpd
    • au démarrage : voir la doc de votre distrib. Avec Gentoo, vous pourrez utiliser /etc/init.d/mpd start


ncmpc
  • à installer sur le serveur pour controler mpd
    • on peut également l'installer sur le client (dans ce cas, pensez à définir un login/password et à ouvrir le port de commande mpd dans le firewall).
mplayer
  • Reçoit le stream et assure son rendu.
  • mplayer http://192.168.1.1:5678
    • 192.168.1.1 est l'ip de la machine faisant tourner mpd.
    • 5678 est le numéro de port utilisé pour envoyer le stream.



Inconvénients de la config du pauvre (mais qui marche tellement bien)

  • Je ne vous le cache pas, il y a quelques inconvénients.
Overhead du tunnel
  • Si vous êtes vraiment court côté débit, sachez qu'un flux à 128kbs (minimum pour une qualité acceptable) vous pompe 16ko/s de bande passante.
    • Avec le tunneling, vous allez passer à environ 22ko/s de moyenne.
  • Je n'ai pas testé avec quelque chose de plus compliqué, à base de OpenVPN par exemple.
    • Si quelqu'un l'a fait, qu'il n'hésite pas à partager son expérience.
  • Pour gagner un peu de bande passante sur la session SSH, vous pouvez passer l'option -N à la connexion.
    • Cette option désactive le shell interactif et ne fait qu'établir le tunnel.
    • Vous ne pourrez donc plus controler la playlist directement, mais pour un streaming tout simple, cela suffit. Vous gagnez environ trois Ko/s.


Latence
  • C'est inhérent au streaming. Pour assurer une liaison sans saccades, tout est bufferisé.
    • Les modifications côté serveurs (changement de chanson, ou arrêt pur et simple) mettront quelques secondes avant d'être répercutées à votre client.
  • Quand à l'avance/retour rapide dans un morceau, mieux vaut oublier tout de suite.
  • Une idée pourrait être de réduire la taille du buffer , sur une liaison de bonne qualité bien entendu.



Allez, c'est pas si mal finalement

  • De toutes façons, vous n'auriez guère mieux avec un serveur shoutcast, alors pourquoi se compliquer la vie ?
  • Allez hop. Et profitez-en pour mettre Audacious à la poubelle avant de sortir.