概要

  • ニコニコ動画の flv/mp4/swf と、コメントのXMLをダウンロードします。

改変元

変更点

  • ファイルの種類に合わせて、拡張子を flv/mp4/swf に変える。
  • 設定ファイルをスクリプトと同じ場所に置く。
  • 保存先も設定ファイルに記述する。
  • ログイン用のURL変更。
  • エコノミーモードの判定を行う。
  • ファイルをバイナリモードで保存。
  • 進捗状況を表示する。
  • オプションなしで起動したときにwarningが出るのに対処。(2009/04/12)
  • openのレイヤーをbytesからrawに変更。(2009/04/12)

ソース

  • nicoget.zip

  • 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

リンク