Mopidy-MPD-mpc

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

nota: ja havia treballat amb mpd i mpc ara fa dos anys en el projecte de les estacions de ràdio de JAZZ:

Mopidy (https://www.mopidy.com/, https://docs.mopidy.com/en/latest/) is an extensible music server written in Python.

Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. You edit the playlist from any phone, tablet, or computer using a range of MPD and web clients.

És a dir, mopidy és el servidor (té una base de dades textual, gestiona les cançons, els tracklist, sap aturar i arrencar una canço, etc.). Per programar aplicacions que treballin contra el servidor puc plantejar-me clients normals (que utilitzaran MPD), o clients WEB.

Mopidy-MPD (https://docs.mopidy.com/en/latest/ext/mpd/) is an extension that provides a full MPD server implementation to make Mopidy available to MPD clients. It is bundled with Mopidy and enabled by default.

Finalment necessito clients. El client més senzilla treballa amb la consola i està escrit en C: mpc (http://www.musicpd.org/clients/mpc/). A solid, lightweight, simple mpd client, written in C (línia de comanda). mpc: A minimalist command line interface to MPD.

Finalment, si tinc un client que funciona en línia de comanda, ha de ser fàcil integrar-ho amb altres aplicacions fent crides de sistema: system().

Per fer el projecte del moble rockola (jukebox), necessito un servidor media player (que sàpiga gestionar una base de dades i tracklist), i un front-end. Com a servidor tinc mopidy, però necessito una interfície per poder programar aplicacions: mpd. Per tant, si soluciono el tema del servidor, només m'hauré de preocupar de fer el front-end.

En aquesta entrada documentaré mopidy-mpd-mpc a Ubuntu. En el projecte real interessa implementar això en la RPi. Un altre tema que consideraré més endavant és que modpidy ja té una base de dades pròpia, i per tant no sé si quan implementi el meu front-end serà realment necessari una base de dades duplicada. (però aquest és un altre tema).

Instal.lació

Instal.lació a Ubuntu:

wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -

Add the following to /etc/apt/sources.list, or if you have the directory /etc/apt/sources.list.d/, add it to a file called mopidy.list in that directory:

# Mopidy APT archive
deb http://apt.mopidy.com/ stable main contrib non-free
deb-src http://apt.mopidy.com/ stable main contrib non-free

For the lazy, you can simply run the following command to create /etc/apt/sources.list.d/mopidy.list:

sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/mopidy.list

Install Mopidy and all dependencies:

sudo apt-get update
sudo apt-get install mopidy

Configuració

De moment no existeix el fitxer de configuració. El pot crear un mateix a ~/.config/mopidy/mopidy.conf, o executant la comanda mopidy es crearà.

$ mopidy
INFO     Starting Mopidy 0.19.4
INFO     Creating dir /home/joan/.local/share/mopidy
INFO     Creating dir /home/joan/.config/mopidy
INFO     Loading config from: builtin defaults, command line options
...

Ara ja puc editar manualment el fitxer de configuració.

Altra informació que es veu:

...
INFO     Starting Mopidy core
INFO     Starting Mopidy frontends: HttpFrontend, MpdFrontend
INFO     HTTP server running at [::ffff:127.0.0.1]:6680
INFO     MPD server running at [::ffff:127.0.0.1]:6600

El servidor ja està esperant col.leccions, ja siguin clients web o de clients MPD.

...
INFO     No local library metadata cache found at /home/joan/.local/share/mopidy/local/library.json.gz. Please run `mopidy local scan` to index your local music library. If you do not have a local music collection, you can disable the local backend to hide this message.
INFO     Loaded 0 local tracks using json
...

Mirant el fitxer de configuració:

#media_dir = $XDG_MUSIC_DIR
#data_dir = $XDG_DATA_DIR/mopidy/local
#playlists_dir = $XDG_DATA_DIR/mopidy/local/playlists

queda clar que $XDG_DATA_DIR per defecte és: /home/joan/.local/share/, que és on es guardarà per defecte la base de dades. Però primer hem d'escanejar la nostra col.lecció, i dir quin és el directori on tenim la col.lecció:

media_dir = /home/joan/musica_rockola
$ mopidy local scan
...
INFO     Found 15 tracks which need to be updated.
INFO     Scanning...
WARNING  Failed local:track:TXARANGO%20-%20Som%20Riu/CLOWNIA.pdf: La vostra instal·lació del GStreamer manca un connector.

...
INFO     Done scanning.

No fer cas a l'últim missatge, és perquè hi ha un pdf que s'ha d'esborrar.

Ara ja tinc la base de dades, i el directori on aniran les playlists:

$ ls /home/joan/.local/share/mopidy/local/
library.json.gz  playlists

I ja puc fer funcionar el servidor:

$ mopidy &
...
INFO     HTTP server running at [::ffff:127.0.0.1]:6680
INFO     MPD server running at [::ffff:127.0.0.1]:6600

Ara he d'instal.lar algun client per poder escoltar els fitxers.

La base de dades

Com hem comentat, la base de dades es troba, segons diu el fitxer de configuració, a $XDG_DATA_DIR/mopidy/local que és /home/joan/.local/share/mopidy/local. Aquí dins es troba l'arxiu library.json.gz, i també es troba la carpeta playlists on aniran a parar les playlists que gravem com a fitxer. Mirar el fitxer json veiem quina és l'estructura. Per a la primera cançó tenim:

{
  "tracks": [
    {
      "composers": [
        {
          "__model__": "Artist",
          "name": "Txarango"
        }
      ],
      "album": {
        "__model__": "Album",
        "name": "Som Riu",
        "artists": [
          {
            "__model__": "Artist",
            "name": "Txarango"
          }
        ]
      },
      "__model__": "Track",
      "name": "Coraz\u00f3n viajero",
      "uri": "local:track:TXARANGO%20-%20Som%20Riu/10%20Coraz%C2%A2n%20viajero.mp3",
      "length": 230384,
      "last_modified": 1394097908,
      "track_no": 10,
      "artists": [
        {
          "__model__": "Artist",
          "name": "Txarango"
        }
      ],
      "date": "2014-01-01",
      "bitrate": 320000
    },
...

Veiem que el root és tracks. Per tant en definitiva és un array de tracks, cada track és un objecte, i s'opta per una definició del track el més general possible. Veiem que per cada track tenim un array de compositors, informació de l'album a que pertany (i l'album conté un array d'artistes), propietats del track, i un array d'artistes que conté el track. Per tant, és una definició molt completa.

mpc: Music Player Client

És un client MPD, de consola, escrit en llenguatge C.

$ sudo apt-get install mpc

$ man mpc
NAME
       mpc - Program for controlling Music Player Daemon (MPD)

SYNOPSIS
       mpc [options] <command> [<arguments>]

DESCRIPTION
       mpc is a client for MPD, the Music Player Daemon.  mpc connects to a
       MPD and controls it according to commands and  arguments  passed  to
       it.   If no command is given, the current status is printed (same as
       'mpc status').
...

Primeres proves:

$ mpc status
volume:100%   repeat: off   random: off   single: off   consume: off

El primer de tot és afegir cançons a la playlist:

       add <file>
              Adds a song from the music database to the playlist. Can also
              read input from pipes. Use "mpc ls |  mpc  add"  to  add  all
              files to the playlist.
$ mpc listall

no es veu res, cosa curiosa. I és que hi ha una mica de confusió. El fitxer de configuració de MPD està a /etc/mpd.conf, i aquí és el lloc correcte per ficar la ruta de les cançons:

$ joe /etc/mpd.conf
...
music_directory         "/home/joan/musica_rockola"
...

Reinicio mopidy, i ara sí:

$ mpc listall
local:track:TXARANGO%20-%20Som%20Riu/01%20Esperan%C2%87a.mp3
local:track:TXARANGO%20-%20Som%20Riu/02%20M%C2%A3sic%20de%20carrer.mp3
local:track:TXARANGO%20-%20Som%20Riu/03%20La%20vuelta%20al%20mundo.mp3
local:track:TXARANGO%20-%20Som%20Riu/04%20Compta%20amb%20mi.mp3
local:track:TXARANGO%20-%20Som%20Riu/05%20El%20meu%20poble.mp3
local:track:TXARANGO%20-%20Som%20Riu/06%20Alegre%20i%20encantada.mp3
local:track:TXARANGO%20-%20Som%20Riu/07%20Som%20un%20riu.mp3
local:track:TXARANGO%20-%20Som%20Riu/08%20Governant.mp3
local:track:TXARANGO%20-%20Som%20Riu/09%20Batega.mp3
local:track:TXARANGO%20-%20Som%20Riu/10%20Coraz%C2%A2n%20viajero.mp3
local:track:TXARANGO%20-%20Som%20Riu/11%20Camp%20de%20batalla.mp3
local:track:TXARANGO%20-%20Som%20Riu/12%20Com%20dues%20gotes%20d%27aigua.mp3
local:track:TXARANGO%20-%20Som%20Riu/13%20Tant%20de%20bo.mp3
local:track:TXARANGO%20-%20Som%20Riu/14%20No%20t%27adormis.mp3

Afegeixo una cançó i la faig sonar:

$ mpc add local:track:TXARANGO%20-%20Som%20Riu/01%20Esperan%C2%87a.mp3

$ mpc ls
Local media

$ mpc playlist
Txarango - Esperança

$ mpc play
Txarango - Esperança
[playing] #1/1   0:00/3:38 (0%)
volume:100%   repeat: off   random: off   single: off   consume: off

Afegim totes les cançons a la playlist:

$ mpc ls |  mpc  add
$ mpc playlist
Txarango - Esperança
Txarango - Esperança
Txarango - Músic de carrer
Txarango - La vuelta al mundo
Txarango - Compta amb mi
Txarango - El meu poble
Txarango - Alegre i encantada
Txarango - Som un riu
...
<pre>
i esborrem la playlist:
<pre>
$ mpc clear

Per mostrar la cançó que està sonant en aquests moments:

$ mpc current
Txarango - Esperança

Tinc una playlist amb dues cançons.

$ mpc playlist
Txarango - Esperança
Txarango - Tant de bo

Si vull eliminar una cançó de la playlist, he de fer del:

del <songpos> Removes a playlist number from the playlist.  Can  also  read
              input from pipes (0 deletes the current playing song).

$ mpc del 1

$ mpc playlist
Txarango - Tant de bo

També hi ha eines per cercar per tag (find, search, findadd, list)

$ mpc list album
Som Riu

mpc: cas pràctic per a la rockola

Es tracta de simular el funcionament de la rockola. Quan poses una moneda, tens dos crèdits i pots escollir dues cançons. Quan esculls la cançó, va a la cua de la playlist (només hi ha una playlist). Ha d'haver-hi un mètode de saber quan una canço s'ha acabat, i retirar-la de la playlist.

Pot ser que una persona posi una moneda mentre està sonant la música. No hi ha problema: les cançons que selecciones s'afegeixen a la playlist.

Per saber quan una cançó acaba, s'ha d'explorar la comanda

$ mpc idle

que espera que hi hagi un event, com ara acabar una cançó (TBD).

Amb tota aquesta informació, es pot fer un joc de proves que simuli la rockola, simulant una moneda amb un scanf.

single mode i consume mode:

The 'single' mode plays song only once, or repeat it if the 'repeat' mode is enabled.

I also implemented the 'consume' mode, which deletes each played song. Patches on mpd, libmpdclient and ncmpc aren't pushed on master repository yet.

Efectivament, el mode consume on funciona. Quan acaba de reproduir-se una cançó, la cançó s'esborra de la playlist. Si tenia 4 cançons, ja només en queden tres.

Simulació rockola

Es tracta de simular el comportament de la rockola. S'engega la màquina i la playlist està a 0. Es fica una moneda=2 crèdits, i puc escollir dues cançons que s'afegeixen a la playlist, i comença a sonar. Ve una altra persona i afegeix dues cançons més, que s'afegeixen a la cua de la playlist. Quan una cançó acaba, desapareix de la playlist (mode consume on). No hi ha cap problema en què es repeteixi una canço. Qualsevol cançó que faig add s'afegeix a la cua.

Amb mpc idle i sobretot mpc idleloop tinc la possibiltiat de capturar els events de quan una cançó canvia. Ara bé, a mi m'interessa captar l'event en un programa C, exactament igual que:

i per sort l'exemple en llenguatge C funciona perfectament:

simulacio_rocola_v1.c:

// https://bbs.archlinux.org/viewtopic.php?id=75518
// gcc prova_v1.c -o prova_v1 -lmpd -I/usr/include/libmpd-1.0/libmpd/
// $ sudo apt-get install libmpd-dev


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libmpd.h>
#include <debug_printf.h>
#define RED "\x1b[31;01m"
#define DARKRED "\x1b[31;06m"
#define RESET "\x1b[0m"
#define GREEN "\x1b[32;06m"
#define YELLOW "\x1b[33;06m"

void status_changed(MpdObj *mi, ChangedStatusType what)
{
        if(what&MPD_CST_SONGID)
        {
                mpd_Song *song = mpd_playlist_get_current_song(mi);
                if(song)
                {
                        printf(GREEN"Song:"RESET" %s - %s\n", song->artist, song->title);
                }
        }

}

int main()
{

        int run = 1, iport = 6600;
        char *hostname = getenv("MPD_HOST");
        char *port = getenv("MPD_PORT");
        char *password = getenv("MPD_PASSWORD");
        MpdObj *obj = NULL;


        if(!hostname) {
                hostname = "localhost";
        }
        if(port){
                iport = atoi(port);
        }

        obj = mpd_new(hostname, iport,password);

        mpd_signal_connect_status_changed(obj,(StatusChangedCallback)status_changed, NULL);
        mpd_set_connection_timeout(obj, 10);

        if(!mpd_connect(obj))
        {
                mpd_send_password(obj);
                do{
                       

                        mpd_status_update(obj);
                }while(!usleep(100000) &&  run);
        }
        return 1;
}

Per compilar:

$ gcc simulacio_rockola_v1.c -o simulacio_rockola_v1 -lmpd -I/usr/include/libmpd-1.0/libmpd/

comprovar que existeix la llibreria libmpd a /usr/include/libmpd-1.0/libmpd/

Si no hi és, s'ha d'instal.lar:

$ sudo apt-get install libmpd-dev

$ ls /usr/include/libmpd-1.0/libmpd/
debug_printf.h     libmpd.h           libmpd-playlist.h  libmpd-strfsong.h
libmpdclient.h     libmpd-internal.h  libmpd-status.h    libmpd-version.h
libmpd-database.h  libmpd-player.h    libmpd-sticker.h

cada vegada que canvia una cançó rebo una notificació:

$ ./simulacio_rockola_v1 
Song: Txarango - Camp de batalla
Song: Txarango - Corazón viajero
...

Mopidy a la RPi

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines