Progetto

Generale

Profilo

Wiki » meta-curl.c

Programma in C per estrarre i metadati dal flusso mp3 - Andrea Belloni, 05-12-2014 14:23

 
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <regex.h>
4
#include <string.h>
5
#include <ctype.h>
6

    
7
#define BUFF_SIZE 4096
8

    
9
/* Converts a hex character to its integer value */
10
char from_hex(char ch) {
11
  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
12
}
13

    
14
/* Converts an integer value to its hex character*/
15
char to_hex(char code) {
16
  static char hex[] = "0123456789abcdef";
17
  return hex[code & 15];
18
}
19

    
20
/* Returns a url-encoded version of str */
21
/* IMPORTANT: be sure to free() the returned string after use */
22
char *url_encode(char *str) {
23
  char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf;
24
  while (*pstr) {
25
    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
26
      *pbuf++ = *pstr;
27
    /* else if (*pstr == ' ') 
28
      *pbuf++ = '+'; */
29
    else 
30
      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
31
    pstr++;
32
  }
33
  *pbuf = '\0';
34
  return buf;
35
}
36

    
37
/* Returns a url-decoded version of str */
38
/* IMPORTANT: be sure to free() the returned string after use */
39
char *url_decode(char *str) {
40
  char *pstr = str, *buf = malloc(strlen(str) + 1), *pbuf = buf;
41
  while (*pstr) {
42
    if (*pstr == '%') {
43
      if (pstr[1] && pstr[2]) {
44
        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
45
        pstr += 2;
46
      }
47
    } else if (*pstr == '+') { 
48
      *pbuf++ = ' ';
49
    } else {
50
      *pbuf++ = *pstr;
51
    }
52
    pstr++;
53
  }
54
  *pbuf = '\0';
55
  return buf;
56
}
57

    
58
int main (void)
59
{
60
  regex_t regexnm, regexgn, regexmi, regexbr, regexrn;
61
  unsigned char buffer[BUFF_SIZE];
62
  unsigned char line[256];
63
  unsigned char *meta[2];
64
  unsigned char icyok = 0;
65
  int count, done = 0;
66
  int reti, br, metaint = 0;
67
  int i, m, n;
68
  int bsize;
69
  char *cp, *urlenc;
70
  char tmpstr[512];
71

    
72
  reti = regcomp(&regexnm, "^icy-name", 0);
73
  reti = regcomp(&regexgn, "^icy-genre", 0);
74
  reti = regcomp(&regexmi, "^icy-metaint", 0);
75
  reti = regcomp(&regexbr, "^icy-br", 0);
76
  reti = regcomp(&regexrn, "^\r\n$", 0);
77

    
78
  cp = fgets(line, 256, stdin);
79
  while (cp != NULL && !done) {
80
    reti = regexec(&regexnm, line, 0, NULL, 0);
81
    if (!reti) {
82
      //fputs(line, stderr);
83
      meta[0] = strtok(line, ":");
84
      meta[1] = strtok(NULL, "\r");
85
      fprintf(stderr, "name=%s\n", meta[1]);
86
      urlenc = url_encode(meta[1]);
87
      sprintf(tmpstr, "curl -s -u root:arduino http://localhost/arduino/name/%c%s%c", '"', urlenc, '"');
88
      system((char *)tmpstr);
89
      //fprintf(stderr, "curl=%s\n", tmpstr);
90
      free(urlenc);
91
    }
92

    
93
    reti = regexec(&regexgn, line, 0, NULL, 0);
94
    if (!reti) {
95
      //fputs(line, stderr);
96
      meta[0] = strtok(line, ":");
97
      meta[1] = strtok(NULL, "\r");
98
      fprintf(stderr, "genre=%s\n", meta[1]);
99
      urlenc = url_encode(meta[1]);
100
      sprintf(tmpstr, "curl -s -u root:arduino http://localhost/arduino/genre/%c%s%c", '"', urlenc, '"');
101
      system((char *)tmpstr);
102
      //fprintf(stderr, "curl=%s\n", tmpstr);
103
      free(urlenc);
104
    }
105

    
106
    reti = regexec(&regexmi, line, 0, NULL, 0);
107
    if (!reti) {
108
      //fputs(line, stderr);
109
      meta[0] = strtok(line, ":");
110
      meta[1] = strtok(NULL, "\r");
111
      metaint = atoi(meta[1]);
112
      fprintf(stderr, "metaint=%i\n", metaint);
113
    }
114

    
115
    reti = regexec(&regexbr, line, 0, NULL, 0);
116
    if (!reti) {
117
      //fputs(line, stderr);
118
      meta[0] = strtok(line, ":");
119
      meta[1] = strtok(NULL, "\r");
120
      br = atoi(meta[1]);
121
      fprintf(stderr, "br=%i\n", br);
122
    }
123

    
124
    reti = regexec(&regexrn, line, 0, NULL, 0);
125
    if (!reti) {
126
      done = 1;
127
      fputs("\n", stderr);
128
    }
129

    
130
    if (!done) {
131
      cp = fgets(line, 256, stdin);
132
    }
133
  }
134

    
135
  if (metaint == 0) {
136
    n = 4;
137
  } else if (metaint > 0) {
138
    bsize = BUFF_SIZE;
139
    if ((metaint % bsize) != 0) {
140
      bsize = 4000;
141
      while ((metaint % bsize) != 0) {
142
        bsize -= 1000;
143
        if (bsize == 0) {
144
          fprintf(stderr, "Error: metaint is not multiple of bsize\n");
145
          return 1;
146
        }
147
      }
148
    }
149
    n = metaint / bsize;
150
  } else {
151
    fprintf(stderr, "Error: metainf less then 0\n");
152
  }
153

    
154
  fprintf(stderr, "bsize=%i\n", bsize);
155

    
156
  while (!feof(stdin)) {
157
    for (i = 0; i < n; i++)
158
    {
159
      count = fread(buffer, 1, bsize, stdin);
160
      fwrite(buffer, 1, count, stdout);
161
    }
162

    
163
    if (metaint > 0) {
164
      count = fread(buffer, 1, 1, stdin);
165
      m = buffer[0];
166

    
167
      if (m != 0) {
168
        count = fread(buffer, 1, m * 16, stdin);
169
        //fwrite(buffer, 1, m * 16, stderr);
170
        //fputs("\n", stderr);
171
        meta[0] = strtok(buffer, "'");
172
        meta[1] = strtok(NULL, "'");
173
        fputs("StreamTitle=", stderr);
174
        fputs(meta[1], stderr);
175
        fputs("\n", stderr);
176
        urlenc = url_encode(meta[1]);
177
        sprintf(tmpstr, "curl -s -u root:arduino http://localhost/arduino/title/%c%s%c", '"', urlenc, '"');
178
        system((char *)tmpstr);
179
        //fprintf(stderr, "curl=%s\n", tmpstr);
180
        free(urlenc);
181
      }
182
    }
183
  }
184

    
185
  return 0;
186
}
(6-6/6)