Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^4: Serving video files in specific byte-ranges

by goofball (Acolyte)
on Sep 06, 2011 at 19:29 UTC ( #924451=note: print w/ replies, xml ) Need Help??


in reply to Re^3: Serving video files in specific byte-ranges
in thread Serving video files in specific byte-ranges

That's a helpful link - thanks! Although, that code uses an HTTP::Response object to pass back to the daemon. Any advice on printing out the response object when not using a daemon? The CPAN docs are entirely clear on this (HTTP::Response and HTTP::Message), and when I implement the print $response->decoded_content in the following code, I get an error of Can't decode ref content at /usr/local/lib/perl5/site_perl/5.8.9/HTTP/Message.pm line 294.

use HTTP::Response; use IO::File; my $response = new HTTP::Response( 404,undef,undef,"404 - Not foun +d." ); $|=1; my $file = new IO::File "< $path"; if (defined $file) { $response->code( 200 ); binmode $file; my $size = -s $file; my ($startrange, $endrange) = (0,$size-1); if (defined $ENV{HTTP_RANGE} and $ENV{HTTP_RANGE} =~ /bytes\s* +=\s*(\d+)-(\d+)?/) { $response->code( 206 ); ($startrange,$endrange) = ($1,$2 || $endrange); }; $file->seek($startrange,0); $response->header(Content_Length => $endrange-$startrange); $response->header(Content_Range => "bytes $startrange-$endrang +e/$size"); $response->content( sub { sysread($file, my ($buf), 16*1024); # No error checking ?? +? return $buf; }); }; print $response->decoded_content;

Another option I tried, just printing the HTTP headers and content to STDOUT, follows below. This prints the requested ranges using a Transfer-Encoding method of chunked, as described here: w3.org and here: Wiki. There are no server-side errors using this script, but the iPhone Safari client still shows a broken file.

my @ranges; if($ENV{HTTP_RANGE} =~ s/^bytes=//i) { @ranges = split /,/, $ENV{HTTP_RANGE}; print "Transfer-Encoding: chunked\n"; warn "printing ranges @ranges\n"; } else { print "Content-length: $filesize\n\n"; } if(@ranges) { open my $fh, '<', $path; foreach $range (@ranges) { my($begin, $end) = split /-/, $range; print "Content_Range: bytes $begin-$end/$filesize\ +n\n"; my $whence = ($begin)? 0 : 2; my $position = ($begin)? $begin : 0 - $end; seek $fh, $position, $whence; if($end) { $range = ($begin)? $end - $begin : $end; my $chunk_header = sprintf("%x", $range); print "$chunk_header\r\n"; sysread $fh, $_ , $range; print "$_\r\n"; warn "printed range of $range bytes from $begi +n to $end\n"; } else { while(<$fh>) { print } } } close $fh; print "0\r\n"; } else { open(FILE, $path) or die; while(<FILE>) { print } close(FILE); }


Comment on Re^4: Serving video files in specific byte-ranges
Select or Download Code
Replies are listed 'Best First'.
Re^5: Serving video files in specific byte-ranges
by Corion (Pope) on Sep 06, 2011 at 20:22 UTC

    Looking at the source of HTTP::Message, it just does not want to decode the content delivered by a callback:

    ... $content_ref = $self->content_ref; die "Can't decode ref content" if ref($content_ref) ne "SCALAR"; ...

    Either you fix HTTP::Message or you try it with ->content() instead of ->decoded_content. Alternatively, look at Plack as your server framework - it should handle callback responses more gracefully than your approach.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://924451]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (19)
As of 2015-07-07 19:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (93 votes), past polls