The music player I recently blogged about required support for mp3/ogg streaming. This meant I either had to serve the actual music through apache (which was what I did at first), or adding support for this to web.py, which RCTK currently uses by default as application server.
This streaming support is defined for HTTP as Partial Content (code 206).
It turned out not to be too hard to implement. At least sufficient support for chrome to accept my streams. The code is as follows
range = web.ctx.env.get('HTTP_RANGE') if range is None: return result total = len(result) _, r = range.split("=") partial_start, partial_end = r.split("-") start = int(partial_start) if not partial_end: end = total-1 else: end = int(partial_end) chunksize = (end-start)+1 web.ctx.status = "206 Partial Content" web.header("Content-Range", "bytes %d-%d/%d" % (start, end, total)) web.header("Accept-Ranges", "bytes") web.header("Content-Length", chunksize) return result[start:end+1]
Put this in your GET method. If no range is defined, it defaults to returning the entire content. If a range is present it will find the requested range, set appropriate headers and return the correct slice.
Here is how the code is used in the RCTK application server implementation.
I suspect this implementation may not be fully bugfree but it works well enough for me. For example:
- Should every response contain the “Accept-ranges: bytes” header to show support for partial content?
- I suspect Chrome ending up in a loop when skipping to the end of a stream
Any improvements are, of course, welcome in the comments.