8 use constant CHUNK_SIZE_BYTES
=> 1024;
12 my $name = $query->param('name');
13 my $filesize = stat($name)->size;
15 # Get throttling rate, assuming parameter is in kilobytes per second.
16 my $kbPerSec = $query->param('throttle');
17 my $chunkPerSec = $kbPerSec * 1024 / CHUNK_SIZE_BYTES
;
19 # Get MIME type if provided. Default to video/mp4.
20 my $type = $query->param('type') || "video/mp4";
22 my $nph = $query->param('nph') || 0;
25 my $contentRange = $ENV{'HTTP_RANGE'};
27 my $rangeEnd = $filesize - 1;
28 my @parsedRange = (0, $rangeEnd);
31 # Handle HTTP Range requests.
36 my @values = split('=', $contentRange);
37 my $rangeType = $values[0];
38 @parsedRange = split("-", $values[1]);
40 if (!$parsedRange[1]) {
41 $parsedRange[1] = $rangeEnd;
43 $httpStatus = "206 Partial Content";
44 $httpContentRange = "bytes " . $parsedRange[0] . "-" . $parsedRange[1] . "/" . $filesize;
46 $httpStatus = "200 OK";
49 print "Status: " . $httpStatus . "\n";
50 print "Connection: close\n";
51 print "Content-Length: " . $filesize . "\n";
52 print "Content-Type: " . $type . "\n";
53 print "Accept-Ranges: bytes\n";
54 if ($httpContentRange) {
55 print "Content-Range: " . $httpContentRange . "\n";
58 # Print HTTP Header, disabling cache.
59 print "Cache-Control: no-cache\n";
60 print "Content-Length: " . $filesize . "\n";
61 print "Content-Type: " . $type . "\n";
66 open FILE
, $name or die;
71 seek(FILE
, $parsedRange[0], 0);
73 while (($n = read FILE
, $data, 1024) != 0) {
77 if (($total >= $filesize) || ($total > $parsedRange[1])) {
81 # Throttle if there is some.
82 if ($chunkPerSec > 0) {
83 select(undef, undef, undef, 1.0 / $chunkPerSec);