Apache-MP3
view release on metacpan or search on metacpan
sub escape {
my $uri = CGI::escape(shift);
# unescape slashes so directories work right with mozilla
$uri =~ s!\%2F!/!gi;
return $uri;
}
# this generates the top-level directory listing
sub process_directory {
my $self = shift;
my $dir = shift;
return $self->list_directory($dir);
}
# this downloads the file
sub download_file {
my $self = shift;
my $file = shift;
my $type = $self->r->content_type;
my $is_audio = $self->supported_type ($self->r->content_type);
if ($is_audio && !$self->download_ok) {
$self->r->log_reason('File downloading is forbidden');
return FORBIDDEN;
} else {
return DECLINED; # allow Apache to do its standard thing
}
}
# stream the indicated file
sub stream {
my $self = shift;
my $r = $self->r;
return DECLINED unless -e $r->filename; # should be $r->finfo
unless ($self->stream_ok) {
$r->log_reason('AllowStream forbidden');
return FORBIDDEN;
}
if ($self->check_stream_client and !$self->is_stream_client) {
my $useragent = $r->headers_in->{'User-Agent'};
$r->log_reason("CheckStreamClient is true and $useragent is not a streaming client");
return FORBIDDEN;
}
my $mime = $r->content_type;
my $file = $r->filename;
my $url = $r->uri;
my $info = $self->fetch_info($file,$mime);
return DECLINED unless $info; # not a legit mp3 file?
my $fh = $self->open_file($file) || return DECLINED;
binmode($fh); # to prevent DOS text-mode foolishness
my $size = -s $file;
my $bitrate = $info->{bitrate};
if ($self->can('bitrate') && $self->bitrate) {
($bitrate = $self->bitrate) =~ s/ kbps//i;
# quick approximation
$size = int($size * ($bitrate / $info->{bitrate}));
}
my $description = $info->{description};
my $genre = $info->{genre} || $self->lh->maketext('unknown');
my $range = 0;
$r->headers_in->{"Range"}
and $r->headers_in->{"Range"} =~ m/bytes=(\d+)/
and $range = $1
and seek($fh,$range,0);
# Look for a descriptive file that has the same base as the mp3 file.
# Also look for various index files.
my $icyurl = $self->stream_base(1);
my $base = basename($file);
$base =~ s/\.\w+$//; # get rid of suffix
my $dirbase = dirname($file);
my $urlbase = dirname($url);
foreach ("$base.html","$base.htm","index.html","index.htm") {
my $file = "$dirbase/$_";
if (-r $file) {
$icyurl .= "$urlbase/$_";
last;
}
}
$r->assbackwards(1);
$r->connection->keepalive(1);
$r->connection->keepalives($r->connection->keepalives+1);
$r->print("ICY ". ($range ? 206 : 200) ." OK$CRLF");
$r->print("icy-notice1: <BR>This stream requires a shoutcast/icecast compatible player.<BR>$CRLF");
$r->print("icy-notice2: Apache::MP3<BR>$CRLF");
$r->print("icy-name: $description$CRLF");
$r->print("icy-genre: $genre$CRLF");
$r->print("icy-url:$icyurl$CRLF");
$r->print("icy-pub:1$CRLF");
$r->print("icy-br:$bitrate$CRLF");
$r->print("Accept-Ranges: bytes$CRLF");
$r->print("Content-Range: bytes $range-" . ($size-1) . "/$size$CRLF")
if $range;
$r->print("Content-Length: $size$CRLF");
$r->print("Content-Type: $mime$CRLF");
$r->print("$CRLF");
return OK if $r->header_only;
if (my $timeout = $self->stream_timeout) {
my $seconds = $info->{seconds};
$seconds ||= 60; # shouldn't happen
my $fraction = $timeout/$seconds;
my $bytes = int($fraction * $size);
while ($bytes > 0) {
my $data;
my $b = read($fh,$data,2048) || last;
( run in 1.415 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )