comparison Plugins/Input/mpg123/mpg123.c @ 354:e2775c9b8b13 trunk

[svn] very rudementary http stream detection support for mpg123-clone. - i had to do a lot of stupid hackish workarounds for shoutcast (BTW, I hate you AOL and I hope you die someday.)
author nenolod
date Thu, 29 Dec 2005 02:29:29 -0800
parents 18f881216679
children 3fb3657d2e14
comparison
equal deleted inserted replaced
353:18f881216679 354:e2775c9b8b13
1 #include "mpg123.h" 1 #include "mpg123.h"
2 #include "common.h"
2 3
3 #include <glib.h> 4 #include <glib.h>
4 #include <glib/gi18n.h> 5 #include <glib/gi18n.h>
5 #include <gtk/gtk.h> 6 #include <gtk/gtk.h>
6 #include <stdlib.h> 7 #include <stdlib.h>
7 #include <string.h> 8 #include <string.h>
9 #include <unistd.h>
10
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/time.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <netdb.h>
8 20
9 #include <libaudacious/util.h> 21 #include <libaudacious/util.h>
10 #include <libaudacious/configdb.h> 22 #include <libaudacious/configdb.h>
11 #include <libaudacious/vfs.h> 23 #include <libaudacious/vfs.h>
12 #include <libaudacious/titlestring.h> 24 #include <libaudacious/titlestring.h>
13 25
14 #include "audacious/util.h" 26 #include "audacious/util.h"
15 27
16 static const long outscale = 32768; 28 static const long outscale = 32768;
29
30 #define BUFSIZE_X 2048
17 31
18 static struct frame fr, temp_fr; 32 static struct frame fr, temp_fr;
19 33
20 PlayerInfo *mpg123_info = NULL; 34 PlayerInfo *mpg123_info = NULL;
21 static GThread *decode_thread; 35 static GThread *decode_thread;
369 done: 383 done:
370 vfs_fclose(file); 384 vfs_fclose(file);
371 return ret; 385 return ret;
372 } 386 }
373 387
388 static gboolean
389 mpg123_detect_by_content_stream(gchar *url)
390 {
391 gchar *buf, inbuf[BUFSIZE_X];
392 struct hostent *hp;
393 struct sockaddr_in sa;
394 gint s, i, y = 0;
395 gchar *user, *pass, *host, *filename;
396 gint port;
397
398 g_strstrip(url);
399
400 parse_url(url, &user, &pass, &host, &port, &filename);
401
402 if (!(s = socket(AF_INET, SOCK_STREAM, 0)))
403 {
404 perror("socket");
405 return FALSE;
406 }
407
408 if ((hp = gethostbyname(host)) == NULL)
409 {
410 g_print("[stream detect] Unable to resolve %s\n", host);
411 close(s);
412 return FALSE;
413 }
414
415 memset(&sa, '\0', sizeof(sa));
416 sa.sin_family = AF_INET;
417 sa.sin_port = htons(port);
418 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
419
420 if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0)
421 {
422 perror("connect");
423 return FALSE;
424 }
425
426 g_print("[stream detect] connected to %s, port %d\n", host, port);
427
428 buf = g_strdup_printf("GET /%s HTTP/1.0\r\nUser-Agent: " PACKAGE "/" PACKAGE_VERSION "\r\n\r\n", filename ? filename : "");
429 i = write(s, buf, strlen(buf));
430 g_free(buf);
431
432 if (i == -1)
433 {
434 perror("write");
435 return FALSE;
436 }
437
438 /* don't ask. --nenolod */
439 while ((i = read(s, inbuf + y, BUFSIZE_X - y)) != 0 && y < BUFSIZE_X)
440 {
441 inbuf[y + i] = '\0';
442 y += i;
443 }
444
445 close(s);
446
447 buf = strtok(inbuf, "\n");
448 while ((buf = strtok(NULL, "\n")) != NULL)
449 {
450 if (!g_strncasecmp("content-type:audio/mpeg", buf, 23) ||
451 !g_strncasecmp("icy-br:", buf, 7) || /* XXX ShoutCAST sometimes doesnt send the content-type header */
452 !g_strncasecmp("Content-Type: audio/mpeg", buf, 24))
453 {
454 g_print("[stream detect] server is providing audio/mpeg stream\n");
455 return TRUE;
456 }
457 }
458
459 g_print("[stream detect] server is NOT providing audio/mpeg stream\n");
460 return FALSE;
461 }
462
374 static int 463 static int
375 is_our_file(char *filename) 464 is_our_file(char *filename)
376 { 465 {
377 char *ext; 466 char *ext;
378 guint16 wavid; 467 guint16 wavid;
379 468
380 /* FIXME: wtf? */ 469 /* FIXME: wtf? */
381 /* We assume all http:// (except those ending in .ogg) are mpeg -- 470 /* We assume all http:// (except those ending in .ogg) are mpeg --
382 * why do we do that? */ 471 * why do we do that? */
383 if (!strncasecmp(filename, "http://", 7)) { 472 if (!strncasecmp(filename, "http://", 7)) {
473 #ifdef NOTYET
384 ext = strrchr(filename, '.'); 474 ext = strrchr(filename, '.');
385 if (ext) { 475 if (ext) {
386 if (!strncasecmp(ext, ".ogg", 4)) 476 if (!strncasecmp(ext, ".ogg", 4))
387 return FALSE; 477 return FALSE;
388 if (!strncasecmp(ext, ".rm", 3) || 478 if (!strncasecmp(ext, ".rm", 3) ||
390 !strncasecmp(ext, ".rpm", 4) || 480 !strncasecmp(ext, ".rpm", 4) ||
391 !strncasecmp(ext, ".ram", 4)) 481 !strncasecmp(ext, ".ram", 4))
392 return FALSE; 482 return FALSE;
393 } 483 }
394 return TRUE; 484 return TRUE;
485 #else
486 return mpg123_detect_by_content_stream(filename);
487 #endif
395 } 488 }
396 if (mpg123_cfg.detect_by == DETECT_CONTENT) 489 if (mpg123_cfg.detect_by == DETECT_CONTENT)
397 return (mpg123_detect_by_content(filename)); 490 return (mpg123_detect_by_content(filename));
398 491
399 ext = strrchr(filename, '.'); 492 ext = strrchr(filename, '.');