App-get_flash_videos

 view release on metacpan or  search on metacpan

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

# Part of get-flash-videos. See get_flash_videos for copyright.
package FlashVideo::RTMPDownloader;

use strict;
use base 'FlashVideo::Downloader';
use IPC::Open3;
use Fcntl ();
use Symbol qw(gensym);
use FlashVideo::Utils;

use constant LATEST_RTMPDUMP => 2.2;

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

  $self->{printable_filename} = $rtmp_data->{flv};

  my $file = $rtmp_data->{flv} = $self->get_filename($rtmp_data->{flv});

  if (-s $file && !$rtmp_data->{live}) {
    info "RTMP output filename '$self->{printable_filename}' already " .
                 "exists, asking to resume...";
    $rtmp_data->{resume} = '';
  }

  if(my $socks = FlashVideo::Mechanize->new->get_socks_proxy) {
    $rtmp_data->{socks} = $socks;
  }

  my($r_fh, $w_fh); # So Perl doesn't close them behind our back..

  if ($rtmp_data->{live} && $self->action eq 'play') {
    # Playing live stream, we pipe this straight to the player, rather than
    # saving on disk.
    # XXX: The use of /dev/fd could go away now rtmpdump supports streaming to
    # STDOUT.

    pipe($r_fh, $w_fh);

    my $pid = fork;
    die "Fork failed" unless defined $pid;
    if(!$pid) {
      fcntl $r_fh, Fcntl::F_SETFD(), ~Fcntl::FD_CLOEXEC();
      exec $self->replace_filename($self->player, "/dev/fd/" . fileno $r_fh);
      die "Exec failed\n";
    }

    fcntl $w_fh, Fcntl::F_SETFD(), ~Fcntl::FD_CLOEXEC();
    $rtmp_data->{flv} = "/dev/fd/" . fileno $w_fh;

    $self->{stream} = undef;
  }

  my $prog = $self->get_rtmp_program;

  if($prog eq 'flvstreamer' && ($rtmp_data->{rtmp} =~ /^rtmpe:/ || $rtmp_data->{swfhash})) {
    error "FLVStreamer does not support "
      . ($rtmp_data->{swfhash} ? "SWF hashing" : "RTMPE streams")
      . ", please install rtmpdump.";
    exit 1;
  }

  if($self->debug) {
    $rtmp_data->{verbose} = undef;
  }

  my($return, @errors) = $self->run($prog, $rtmp_data);

  if($return != 0 && "@errors" =~ /failed to connect/i) {
    # Try port 443 as an alternative
    info "Couldn't connect on RTMP port, trying port 443 instead";
    $rtmp_data->{port} = 443;
    ($return, @errors) = $self->run($prog, $rtmp_data);
  }

  if($file ne '-' && (-s $file < 100 || !$self->check_file($file))) {
    # This avoids trying to resume an invalid file
    error "Download failed, no valid file downloaded";
    unlink $rtmp_data->{flv};
    return 0;
  }

  if($return == 2) {
    info "\nDownload incomplete -- try running again to resume.";
    return 0;
  } elsif($return) {
    info "\nDownload failed.";
    return 0;
  }

  return -s $file;
}

sub get_rtmp_program {
  if(is_program_on_path("rtmpdump")) {



( run in 1.474 second using v1.01-cache-2.11-cpan-140bd7fdf52 )