Filter::FetchNicoVideoを、ローカルにFLVがあったらアクセスしないようにした
- ゆーすけべー日記: Plaggerでニコニコ動画を一括ダウンロード&変換 Podcast を生成して iPod touch で見る - 2007年11月最新版
- フッ君の日常 : Filter::FetchNicoVideo にウェイトを入れてみた
後者の記事にあるとおり、確かに、
Plagger でニコニコ動画をダウンロード&変換できるようになったのはいいんですが、すでに変換済みの動画がローカルに大量にあったりすると、
短時間に多数のアクセスが発生
- > ニコニコ運営側に怒られる
- > 動画が(一時的に)ダウンロードできなくなる
という悲しい事態が発生してしまいます。
は発生するのですが、だったらローカルに動画があるときはニコニコ動画にアクセスしなければいいのでは?と思ったのでcodereposのSVNの最新をベースに、手元で修正してみました。
ローカルに動画があるときは、
- $enclosure->urlはセットしない(どうせ使わないから)
- $enclosure->lengthには、statでファイルサイズを取得して突っ込む
としており、乱暴な気がしないでもないですが、この使い方では今のところ困っていません。
diffは以下の通り。
Index: FetchNicoVideo.pm =================================================================== --- FetchNicoVideo.pm (リビジョン 2815) +++ FetchNicoVideo.pm (作業コピー) @@ -51,6 +51,28 @@ #get video_id my ($video_id) = $entry->link =~ m!www.nicovideo.jp/watch/(.*)!; + #set local path + my $filename = $self->conf->{id_as_filename} ? $video_id : $entry->title; + utf8::encode($filename); + if ( $self->conf->{filename_encode} ) { + Encode::from_to( $filename, "utf-8", $self->conf->{filename_encode} ); + } + my $path = File::Spec->catfile( $self->conf->{dir}, $filename . ".flv" ); + + # declare new enclosure + my $enclosure = Plagger::Enclosure->new; + $enclosure->media_type("video/x-flv"); + $enclosure->filename($filename); + $enclosure->local_path($path); # set to be used in later plugins + + if ( -e $path ) { + $context->log( info => "$filename is already exists" ); + my $filesize = (stat $path)[7]; + $enclosure->length($filesize); # use file size instead of Content-Length + $entry->add_enclosure($enclosure); + return; + } + #get flv url my $res = $ua->get("http://www.nicovideo.jp/api/getflv?v=$video_id"); my $q = CGI->new( $res->content ); @@ -62,28 +84,16 @@ } $context->log( info => "Found FLV URL $flv_url" ); - my $enclosure = Plagger::Enclosure->new; $enclosure->url( URI->new($flv_url) ); - $enclosure->media_type("video/x-flv"); - #set local path - my $filename = $self->conf->{id_as_filename} ? $video_id : $entry->title; - utf8::encode($filename); - if ( $self->conf->{filename_encode} ) { - Encode::from_to( $filename, "utf-8", $self->conf->{filename_encode} ); - } - my $path = File::Spec->catfile( $self->conf->{dir}, $filename . ".flv" ); - #access video page $ua->get("http://www.nicovideo.jp/watch/$video_id"); #download flv file - unless ( -e $path ) { - my $req = HTTP::Request->new(GET => $enclosure->url); - $context->log(info => "Fetching $video_id FLV File from " . $enclosure->url . "..." ); - my $res = $ua->request($req, $path); - $context->log(warn => "Fetch FLV Error: $video_id" ) if $res->is_error; - } + my $req = HTTP::Request->new(GET => $enclosure->url); + $context->log(info => "Fetching $video_id FLV File from " . $enclosure->url . "..." ); + my $res = $ua->request($req, $path); + $context->log(warn => "Fetch FLV Error: $video_id" ) if $res->is_error; #download xml file if ( $self->conf->{download_comment} ) { @@ -101,8 +111,6 @@ } } - $enclosure->filename($filename); - $enclosure->local_path($path); # set to be used in later plugins if ($res->header('Content-Length') ) { $enclosure->length( $res->header('Content-Length') ); }
追記
>kamawadaさん(ゆーすけべーさん?)
Plagger的にはDedupedをうまく使うってのが解決方法かな。俺はそうしてる。Plugin側で対応してもいいけど。
なるほど、Dedubpedという存在をすっかり忘れてました。ただ、私の使い方は「ジャンルごとにマイリストを作ってcronで毎日深夜に一気に更新を取得する」で、この場合1日更新分の取得を忘れると、DedupedでPodcastのRSSから除外されてしまい、iPodに入れられなくなるのではないかと思うのです。
また、元のプラグインで、FLVがローカルに存在する場合には新たにダウンロードしないようにされていますが、それでも動画ページへのアクセスは一度行っています。上記はこれを行わないように修正しています。
コメントをDLする場合のことは全く考えてないんですけどね…。