nicoget.pl
#!/usr/local/bin/perl
#
# nicoget.pl,v 0.1+0.2 2009/04/12 15:00:00 take-ash
#
# original: http://blog.livedoor.jp/dankogai/archives/50885358.html
# original: http://blog.livedoor.jp/dankogai/archives/51141631.html
use strict;
use warnings;
use utf8;
use LWP::UserAgent;
use HTTP::Cookies;
use HTTP::Request;
use HTTP::Headers;
use CGI;
use YAML::Syck;
my %Ext = ( 'f'=>'flv', 'm'=>'mp4', 's'=>'swf', );
my $yaml = "./nicovideo.yml";
my $conf = YAML::Syck::LoadFile($yaml) or die "$yaml:$!";
my $savepath = $conf->{ 'savepath' };
delete $conf->{ 'savepath' };
if ( $savepath !~ /[\/|\\]$/ ){
$savepath .= '/';
}
my $video_id = $ARGV[0] or die "usage: $0 [video_id|uri]\n";
$video_id =~ /((sm|nm|ca)?\d+)(\?.*)?$/;
$video_id = $1;
my $ua = LWP::UserAgent->new( keep_alive => 4 );
$ua->cookie_jar( {} );
warn "login as $conf->{mail}\n";
$ua->post( "https://secure.nicovideo.jp/secure/login?site=niconico" => $conf );
$ua->get("http://www.nicovideo.jp/watch/$video_id");
my $res = $ua->get("http://www.nicovideo.jp/api/getflv?v=$video_id");
my $q = CGI->new( $res->content );
my $uri = $q->param('url') or die "Failed: " . $res->content;
$uri =~ /\/smile\?(.)\=[\d\.]+(\w+)?$/;
my $ext = $Ext{ $1 } || 'flv';
my $low = ( defined( $2 ) ) ? $2 : "" ;
my $filename = $savepath."$video_id$low.$ext";
my $req = HTTP::Request->new(
GET => $uri
);
if ( $low ){
warn "economy mode\n";
}
savewithprogress( $req, $filename );
$filename = $savepath."$video_id$low.xml";
my $header = HTTP::Headers->new;
$header->header( Content_Type => 'text/xml' );
my $thread_id = $q->param('thread_id');
$req = HTTP::Request->new(
POST => $q->param('ms'),
$header,
qq{<thread res_from="-500" version="20061206" thread="$thread_id" />}
);
savewithprogress( $req, $filename );
exit();
sub savewithprogress {
my( $req, $filename ) = @_;
my $uri = $req->uri;
warn "$filename <= $uri\n";
open my $wfh, '>:raw', "$filename" or die "$filename:$!";
$res = $ua->request(
$req,
sub {
my ( $chunk, $res, $proto ) = @_;
print $wfh $chunk;
my $size = tell $wfh;
if (my $total = $res->header('Content-Length')){
printf STDERR ( "%d/%d (%.1f%%)\r", $size, $total, $size / $total * 100 );
} else {
printf STDERR ( "%d/Unknown bytes\r", $size );
}
}
);
close $wfh;
warn "\n", $res->status_line, "\n";
}
# EOF
nicovideo.yml
mail: your@host.name
password: yourpassword
savepath: C:/temp