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");
