Apache-MP3

 view release on metacpan or  search on metacpan

MP3.pm  view on Meta::CPAN


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 )