Christopher Zenzel
2008-Nov-29 21:05 UTC
[Icecast-dev] Icecast Streaming to an iPhone or iPod touch
Hello everyone, I have created a patch that allows an iPod touch or iPhone with "CoreMedia" to receive Icecast streams directly from the server. I did modify the original patch from the mailing list to include user agent switching for CoreMedia vs. other browsers. Please let me know how it works. I have been streaming a local weather radio on Icecast with the iPhone patch (attached) has been working great! Thanks, Christopher Zenzel --- src/format.c 2008-04-19 23:24:30.000000000 -0400 +++ src/format.c 2008-11-29 15:50:59.000000000 -0500 @@ -280,12 +280,32 @@ avl_node *node; ice_config_t *config; + /* Partial hack, check for range and user agent in this function */ + const char *useragent; + useragent = httpp_getvar (client->parser, "user-agent"); + int appledevicesupp = 0; + + if (useragent && strstr(useragent, "CoreMedia")) { + appledevicesupp = 1; + } + remaining = client->refbuf->len; ptr = client->refbuf->data; client->respcode = 200; - bytes = snprintf (ptr, remaining, "HTTP/1.0 200 OK\r\n" - "Content-Type: %s\r\n", source->format->contenttype); + if (!appledevicesupp) { + bytes = snprintf (ptr, remaining, "HTTP/1.0 200 OK\r\n" + "Content-Type: %s\r\n", source->format->contenttype); + } else { + char *range = httpp_getvar(client->parser, "range"); + if (range) { + bytes = snprintf(ptr, remaining, "HTTP/1.1 206 Partial Content\r\n" + "Content-Type: %s\r\n", source->format->contenttype); + } else { + bytes = snprintf(ptr, remaining, "HTTP/1.0 200 OK\r\n", + "Content-Type: %s\r\n", source->format->contenttype); + } + } remaining -= bytes; ptr += bytes; --- src/format_mp3.c 2007-10-18 23:02:35.000000000 -0400 +++ src/format_mp3.c 2008-11-29 15:50:49.000000000 -0500 @@ -658,6 +658,53 @@ ptr += bytes; } + /* hack for iPhone OS or Simulator with CoreMedia. checks user agent then adds iPhone-specific headers */ + char *range; + range = httpp_getvar(client->parser, "range"); + int appledevicesupp = 0; + if (useragent && strstr(useragent, "CoreMedia")) { + appledevicesupp = 1; + } + if (appledevicesupp) + { + int rangenumber; + int rangenumber2; + if (range != NULL) { + int ret = 0; + int rangeproblem = 0; + ret = sscanf(range, "bytes=%d-%d", &rangenumber, &rangenumber2); + if (ret != 2) { + rangeproblem = 1; + } + if (rangenumber < 0) { + rangeproblem = 1; + } + if (!rangeproblem) { + char currenttime[50]; + time_t now; + int strflen; + struct tm result; + time(&now); + strflen = strftime(currenttime, 50, "%a, %d-%b-%Y %X GMT", + gmtime_r(&now, &result)); + client->respcode = 206; + bytes = snprintf(ptr, remaining, "Date: %s\r\n", currenttime); + if (bytes > 0) + { + remaining -= bytes; + ptr += bytes; + } + bytes = snprintf(ptr, remaining, "Content-Range: bytes %d-%d/221183499\r\n", + rangenumber, rangenumber2); + if (bytes > 0) + { + remaining -= bytes; + ptr += bytes; + } + } + } + } + client->format_data = client_mp3; client->free_client_data = free_mp3_client_data; metadata = httpp_getvar(client->parser, "icy-metadata");