I’m trying to build a standalone server for Roku that will stream content from my local computer and I run into a problem (I’m using Delphi for development).
If I send the whole video as a stream, Roku will play the video nice to about minute 30 and then won’t work anymore. If I stream the same video from Apache server, the video will play without problems…
I looked in Apache logs and I see that Roku makes multiple requests for the same video:
Can someone please explain to me, just in few words how the communication between Roku and the server should be handled? I need a good simple explanation
My first atempt, that plays about 30 min into the video looks like this on the sever side:
if FileExists(LFilename) then
begin
AResponseInfo.ContentType := 'video/mp4';
AResponseInfo.ContentStream := TIdReadFileExclusiveStream.Create(LFilename);
end;
TIA
P.S.: This is going to be open source, so anyone can play with it when I have a working version.
The Roku seems to use open ended range requests with a reset of that connection after it receives a chunk of data it deems appropriate. It will then send another open ended range request beginning where it last got data from.
P.S. I may be way off on this, but that seems to be what I remember from testing and examining packet captures.
“greubel” wrote:
Your server needs to be able to handle partial transfers and addressing over 2 gig.
The format of mpeg movies is such that Roku needs to randomly access the video container to get parameters and data locations.
How does Roku requests a partial transfer? Do you have a request example (request header), and what should the server answer to that request?
“greubel” wrote:
Your server needs to be able to handle partial transfers and addressing over 2 gig.
The format of mpeg movies is such that Roku needs to randomly access the video container to get parameters and data locations.
How does Roku requests a partial transfer? Do you have a request example (request header), and what should the server answer to that request?
It uses the Range header…
You must return 206, not 200, when responding to a range request. This is standard – see section 14.35 in the HTTP 1.1 spec. You can also return 416 if the requested range is completely outside the file (so no bytes would be returned).
20K blocks … starting from where? Do you keep a status for each Roku and you answer with the next block?
So for example, to the first request, the one without range, you send 0 to 20K, to the second one 20+1 to 41… etc?
If a request comes with range, do you still send your next 20K block using the range or just the next one that you didn’t send yet (ignoring the range)?
I understand that part, when a request comes for a range you send the range in blocks of 20K. I’ll setup my communication buffer to 20K too.
What I don’t understand is what if a request comes and doesn’t have a range? What do I answer to that one?
User-Agent: Roku/DVP-2.9 (012.09E01529A)
GET /Ancient%20Aliens/Ancient%20Aliens_20110126_20002100.mp4 HTTP/1.1
For this one, the Range start and Range end are both 0, and I saw those kind of request coming in the server at random times from Roku… should I just ignore those requests?
Hi, can someone give me some tips on what to look for in making sure a server is correctly responding to range requests, for instance how to compare two server’s responses (one that works and one that doesn’t) to figure out what the difference is? I’m messing around in Wireshark, but not sure the best way to proceed with figuring out the differences.
The things to look for in the second case are that the first line of the headers should be “206 Partial Content” rather than “200 OK”, Content-Length should be “1”, and there should be a “Content-Range” header. And of course output2 should contain one byte, the second byte that is in output1. Both commands should return an “Accept-Ranges: bytes” header.