MPD steuern und auslesen mit libmpdclient

Gast #4158076
Lesenswert?
• ▲
▼
Hallo,

hier habe ich bereits einen Anfang gefunden.
https://www.mikrocontroller.net/articles/MPD_Client_Programming

Da geht es lediglich um das steuern des MPD Servers mithilfe von C. Das 
klappt bei mir auch soweit schon ganz in Ordnung, habe nur ein bisschen 
getestet. Syntax ist nicht ganz wie dort angegeben zB. erwartet 
mpd_send_pause mehr als 1 Attribut.

Nun jedoch möchte ich auch den Status des Displays ablesen und auf ein 
LCD16x02/20x04 Display darstellen. Die Libery verfügt leider aber über 
kein übersichtliches Tutorial/ Wiki oder Dokumentation.

http://www.musicpd.org/libs/libmpdclient/
1
int main(void)
2
{
3
  struct mpd_status *status;
4
  printf("%03i\n", mpd_status_get_volume(status));
5
}
 geht es leider nicht.
Gast #4158105
Lesenswert?
• ▲
▼
Hi,

schau Dir mal die Quellen von lcd4linux an, wo dies bereits 
implementiert wurde.

https://lcd4linux.bulix.org/browser/trunk/plugin_mpd.c


Vom Prinzip her sind folgende Lib-Aufrufe notwendig, (auf die schnelle 
ohne eine Fehlerbehandlung)
1
conn = mpd_connection_new(host, iport, TIMEOUT_IN_S * 1000);
2
if (*pw && !mpd_run_password(conn, pw) { ... }
3

4
mpd_command_list_begin(conn, true);
5
mpd_send_status(conn);
6
mpd_command_list_end(conn);
7
status = mpd_recv_status(conn);
8
l_volume = mpd_status_get_volume(status);
9

10
mpd_connection_free(conn);

MfG, Nick
Gast #4158179
Lesenswert?
• ▲
▼
Hallo musical native,

ja wäre es. Damit habe ich mich zu anfang mit beschäftigt. Aber es wird 
immer wieder gesagt, dass man nicht zwingend mit fopen alles abfragen 
soll. Die Ausgaben gibt es ja teilweise gut formatiert.
Gast #4158214
Lesenswert?
• ▲
▼
Könnte mir wer hier einen einfachen Code in C bereit stellen, der einen 
Linux Shell Befehl an die Console abgibt und den Rückgabewert einließt?
1
[root@alarmpi mpd]# mpc -f "%artist%"
1
Fall Out Boy
2
[playing] #4/24   1:42/3:52 (43%)
3
volume: 65%   repeat: on    random: on    single: off   consume: off
Gast #4158335
Lesenswert?
• ▲
▼
Hab es nun mal so versucht,
1
  char command[] = "mpc -f \"\%artist\%\"";
2
  char Buffer[200];
3
  FILE *f = popen("mpc", "r");
4
  if (f != NULL) {
5
    while (fgets(Buffer, sizeof(Buffer), f) != NULL) printf("%s\n", Buffer);
6
    pclose(f);
7
  }
8

9
  int i = 0;
10
  while (Buffer[i] != '\n') {
11
    title[i] += Buffer[i]; i++;
12
  }
13
  title[i + 1] = '\0';
14
  printf(":%s:\n", title);

Die Ausgabe passt leider nicht zu [*]mpc -f "%artist"[/*]
1
Slipknot - Duality
2

3
[playing] #2/24   1:17/4:15 (30%)
4

5
volume: 36%   repeat: on    random: on    single: off   consume: off
6

7
:volume: 36%   repeat: on    random: on    single: off   consume: off:
Gast #4158361
Lesenswert?
• ▲
▼
1
void getInfo(void)
2
{
3
  char command[] = "mpc -f \"\%artist\%\"";
4
  char Buffer[200];
5
  FILE *f = popen("mpc", "r");
6
  
7
  if (f != NULL) {
8
    while (fgets(Buffer, sizeof(Buffer), f) != NULL); // printf("%s", Buffer);
9
    pclose(f);
10
  }
11
  else printf("File konnte nicht geoeffnet werden\n");
12

13
  printf("<\n%s>\n", Buffer);
14
}

Das Problem scheint zu sein, dass hier nur die letzte Zeile ausgelesen 
wird, bzw. übergeben wird. Leider kann ich mit mpc nicht einzelne Zeilen 
ausgeben, die letzten beiden kommen immer, egal welches Format ich 
verwende.
Gast #4158455
Lesenswert?
• ▲
▼
Ich bin nun ein ganzes Stück weitergekommen. Nun habe ich die 
Möglichkeit, Titel und Künstler auszulesen.
1
int readStream(void)
2
{
3

4
  readLine(0, "mpc -f \"\%artist\%\"");
5
  strncpy(artist, buffer, MAX_BUFFER);
6
  artist[sizeof(artist) - 2] = ' ';
7

8
  readLine(0, "mpc -f \"\%title\%\"");
9
  strncpy(title, buffer, MAX_BUFFER);
10

11
  readLine(2, "mpc -f \" \"");  // Platzhalter
12
  strncpy(line1, buffer, MAX_BUFFER);
13
  if (strstr(line1, "[playing]")) state = 2;
14
  else if (strstr(line1, "[paused]")) state = 1;
15
  else state = 0;
16

17
  readLine(3, "mpc");
18
  strncpy(line2, buffer, MAX_BUFFER);
19
}
20

21
int readLine(int line, char* cmd)
22
{
23
  char Buffer[200];
24
  FILE *f = popen(cmd, "r");
25
  char *ptr;
26
  int i;
27

28
  // verwerfen
29
  for (i = 0; i < line - 1; i++) if (fgets(tempBuffer, MAX_BUFFER, f) == NULL) return (int)NULL;
30
  // schreiben
31
  if (fgets(buffer, MAX_BUFFER, f))
32
  {
33
    ptr = strchr(buffer, '\n');
34
    if (ptr) *ptr = '\0';
35
    return (int)NULL;
36
  }
37
}

Nun die Frage, wie kann ich folgende Zeilen am besten splitten, sodass 
ich folgende Werte erhalte
1
[playing] #8/24   3:23/3:27 (98%)
2
volume:  9%   repeat: on    random: on    single: off   consume: off

Nach playing und pause kann ich bereits suchen.
Nun müsste ich noch folgende Werte erhalten

#8/24 -> int actTrack = 8; int maxTrack = 24;
3:23/3:27 -> char chElapTime[] = {"3:23"}; char chTotalTime = {"3:27"};
volume:  9% -> int vol = 9;
repeat: on -> int repeat = 1;
....
Gast #4158499
Lesenswert?
• ▲
▼
Mit
http://libmpdclient.sourcearchive.com/documentation/2.2/example_8c-source.html

und
1
gcc example.c -lmpdclient && ./a.out

ergibt sich innerhalb 1 Minute spielend leicht:
1
version[0]: 0
2
version[1]: 19
3
version[2]: 0
4
volume: 97
5
repeat: 0
6
queue version: 2
7
queue length: 14
8
song: 6
9
elaspedTime: 56
10
elasped_ms: 55511
11
totalTime: 345
12
bitRate: 192
13
sampleRate: 44100
14
bits: 24
15
channels: 2
16
uri: Iron Maiden - 06 - Strange World.mp3
17
artist: Iron Maiden
18
album: Iron Maiden
19
title: Strange World
20
date: 1981
21
time: 345
22
pos: 6

Du kannst natürlich auch den output von mpc mit RE zerfleischen. Viel 
Spass.
Gast #4158855
Lesenswert?
• ▲
▼
Hallo,

ja ich hab nochmals die lib angeschaut. Hab nun auch alles soweit 
auslesen können, solange es keine Zeichenkette ist.

Folgendes Problem, ich würde gerne die MP3-Tags auslesen und in ein 
struct speichern, um es entsprechend aufrufen zu können.

1
#define MAX 30
2
struct mpd_tags {
3
  char artist[MAX];
4
  char title[MAX];
5
};
6

7
static void mpd_get_tags(struct mpd_tags *tags, const struct mpd_song *song) {
8
  unsigned i = 0;
9
  const char *value;
10

11
  while ((artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, i++)) != NULL)
12
  {
13
  strcpy(tags->artist, value);
14
  }
15
  i = 0;
16

17
  while ((title = mpd_song_get_tag(song, MPD_TAG_TITLE, i++)) != NULL)
18
  {
19
  strcpy(tags->title, value);
20

21
  }
22
  printf(tags->artist); printf("\n");
23
  printf(tags->title); printf("\n");
24
}
25

26
int main (void)
27
{
28
  struct mpd_tags *tags;
29
  while (1) {
30
    if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
31
      mpd_get_tags(tags, song);
32
      if (song != NULL) {
33
        lcdPosition(lcd, 0, 0);
34
        lcdPuts(lcd, tags->artist);
35
        lcdPosition(lcd, 0, 1);
36
        lcdPuts(lcd, tags->title);
37

38
        mpd_song_free(song);
39
      }
40
    }
41
  }
42
}

Hier erhalte ich den Fehler

lcd.c: In function 'mpd_get_tags':
error: 'artist' undeclared (first use in this function)
  while ((artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, i++)) != NULL)
          ^
note: each undeclared identifier is reported only once for each function 
it appears in
error: 'title' undeclared (first use in this function)
  while ((title = mpd_song_get_tag(song, MPD_TAG_TITLE, i++)) != NULL)
          ^

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren