App-get_flash_videos

 view release on metacpan or  search on metacpan

lib/FlashVideo/RTMPDownloader.pm  view on Meta::CPAN

  return "rtmpdump";
}

sub get_command {
  my($self, $rtmp_data, $debug) = @_;

  return map {
    my $arg = $_;

    (ref $rtmp_data->{$arg} eq 'ARRAY'
      # Arrayref means multiple options of the same type
      ? (map {
        ("--$arg" => $debug
          ? $self->shell_escape($_)
          : $_) } @{$rtmp_data->{$arg}})
      # Single argument
      : ("--$arg" => (($debug && $rtmp_data->{$arg})
        ? $self->shell_escape($rtmp_data->{$arg})
        : $rtmp_data->{$arg}) || ()))
  } keys %$rtmp_data;
}

sub run {
  my($self, $prog, $rtmp_data) = @_;

  debug "Running $prog", join(" ", $self->get_command($rtmp_data, 1));

  my($in, $out, $err);
  $err = gensym;
  my $pid = open3($in, $out, $err, $prog, $self->get_command($rtmp_data));

  # Windows doesn't send signals to child processes, so we need to do it
  # manually to ensure that we don't have stray rtmpdump processes.
  local $SIG{INT};
  if ($^O =~ /mswin/i) {
    $SIG{INT} = sub {
      kill 'TERM', $pid;
      exit;
    };
  }

  my $complete = 0;
  my $buf = "";
  my @error;

  while(sysread($err, $buf, 128, length $buf) > 0) {
    $buf =~ s/\015\012/\012/g;

    my @parts = split /\015/, $buf;
    $buf = "";

    for(@parts) {
      # Hide almost everything from rtmpdump, it's less confusing this way.
      if(/^((?:DEBUG:|WARNING:|Closing connection|ERROR: No playpath found).*)\n/) {
        debug "$prog: $1";
      } elsif(/^(ERROR: .*)\012/) {
        push @error, $1;
        info "$prog: $1";
      } elsif(/^([0-9.]+) kB(?:\s+\/ \S+ sec)?(?: \(([0-9.]+)%\))?/i) {
        $self->{downloaded} = $1 * 1024;
        my $percent = $2;

        if($self->{downloaded} && $percent != 0) {
          # An approximation, but should be reasonable if we don't have the size.
          $self->{content_length} = $self->{downloaded} / ($percent / 100);
        }

        $self->progress;
      } elsif(/\012$/) {
        for my $l(split /\012/) {
          if($l =~ /^[A-F0-9]{,2}(?:\s+[A-F0-9]{2})*\s*$/) {
            debug $l;
          } elsif($l =~ /Download complete/) {
            $complete = 1;
          } elsif($l =~ /\s+filesize\s+(\d+)/) {
            $self->{content_length} = $1;
          } elsif($l =~ /\w/) {
            print STDERR "\r" if $self->{downloaded};
            info $l;

            if($l =~ /^RTMPDump v([0-9.]+)/ && $1 < LATEST_RTMPDUMP) {
              error "==== Using the latest version of RTMPDump (version "
                . LATEST_RTMPDUMP . ") is recommended. ====";
            }
          }
        }

        if(/open3/) {
          error "\nMake sure you have 'rtmpdump' or 'flvstreamer' installed and available on your PATH.";
          return 0;
        }
      } else {
        # Hack; assume lack of newline means it was an incomplete read..
        $buf = $_;
      }
    }

    # Should be about enough..
    if(defined $self->{stream} && $self->{downloaded} > 300_000) {
      $self->{stream}->();
    }
  }

  waitpid $pid, 0;
  return $? >> 8, @error;
}

1;



( run in 2.312 seconds using v1.01-cache-2.11-cpan-99c4e6809bf )