2009年07月26日

動画のファイルサイズをチェックする。

get_video_infoで動画情報が取得できたので
ダウンロード前にファイルサイズのチェックをしてみた。
CurlでやっているけれどLWPでもできんでしょ。
入口部分を丁寧にしてみた。


#!/usr/bin/perl
use WWW::Curl::Easy;
use URI::Escape;

my $uri2= `xclip -selection clipboard -o`;
my ($yurl,$uri3);
($yurl, $uri3) = split(/\?/, $uri2);

my @uriprm =split(/&/,$uri3);
$uriprm[0]=~ /v=(.+?)$/;
my $ID=$1;
if (($ID eq '')||($yurl ne 'http://www.youtube.com/watch')){
print "not youtube\n";
exit;
}
my $url = 'http://www.youtube.com/get_video_info?video_id='.$ID;


取り敢えず「?」でURLとパラメータに分けてパラメータ第一データをIDとして取り
urlがyoutubeでないかIDが空白ならば終了。

省いてもたいした量じゃないので昨日と同じCurlの初期化と
動画情報の読み込み



my $rbody;
open (my $FH, "+>", \$rbody);
my $curl = WWW::Curl::Easy->new();
$curl->setopt( CURLOPT_WRITEDATA, $FH);
$curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
$curl->setopt( CURLOPT_URL, $url );
$curl->setopt(CURLOPT_TIMEOUT, 30);

my $resp = $curl->perform;
$curl->close;


パラメータ分解

my @prms = split(/&/,$rbody);
my ($name, $val);
my %param = {};
foreach ( @prms ) {
($name, $val) = split(/=/, $_);
$param{ $name } = ($val);
}
my $t = $param{'token'};
print("$t\n");
my $status=$param{'status'};
print("$status\n");
if ($status eq 'fail'){
print 'アクセスできません';
exit(1);
}
my $author = $param{'author'};
print("author:$author\n");
my $title = uri_unescape($param{'title'});
print("title:$title\n");
my $keywds = uri_unescape($param{'keywords'});
print("keywords:$keywds\n");
my $vid = $param{'video_id'};
my $v_len = $param{'length_seconds'};
print("$v_len sec\n");
my $thumb = uri_unescape($param{'thumbnail_url'});

my $fmt = uri_unescape($param{'fmt_map'});
$fmt =~/(.+?)\//;
my $fm=$1;
if (($fm !=22) && ($fm !=35)){$fm =18;}
#if ($fm ==22){$fm=35;}
#if ($fm !=35){$fm=18;}
my $ext = $fm !=35? 'mp4':'flv';

my $mp4url="http://www.youtube.com/get_video?video_id=$vid&t=$t&fmt=$fm";
print("url:\n$mp4url\n");


format22と35以外の時は18、
動画フォーマットが35の時はflv、
22が18の時は拡張子をmp4にした。
ここはperl版でもユーザー操作をはさむ予定。

ここで動画を直接ダウンロードせずにヘッダーだけ読む

$curl->setopt(CURLOPT_NOBODY,1);
$curl->setopt( CURLOPT_URL, $mp4url );
$resp = $curl->perform;

print $curl->getinfo( CURLINFO_CONTENT_TYPE)."\n";
print $curl->getinfo( CURLINFO_HTTP_CODE)."\n";
print $curl->getinfo( CURLINFO_EFFECTIVE_URL)."\n";
print $curl->getinfo( CURLINFO_CONTENT_LENGTH_DOWNLOAD)."bytes \n";
$curl->close;
close($FH);



CURLINFO_EFFECTIVE_URLで得られる値は最終的なURLだけれど
ずいぶんと長い物になっていた。

目的のファイルサイズは「CURLINFO_CONTENT_LENGTH_DOWNLOAD」で
Content-lengthほ求めることができる。

CURLINFO_HTTP_CODEは成功していれば200がくる。
cgiでダメな場合は
最初のリクエストでREFERERを入れて

$curl->setopt(CURLOPT_AUTOREFERER, 1 );


あたりいれれば良いのだろうがとりあえずローカルアクセスでは問題がなかった。
現実問題としてダウンロード前にサイズがしれたらと思ったのだが
フォーマット決定しないとファイル名が確定しないのでコンソールでもUI入れるなら
header取得はループブロックにする必要がありそうだ。

ダウンロードする時はユーザーにファイル名を入力させるか
id名にする。ファイルハンドルを開かないといけないのはLWPよりめんどいところ

手持ちの中程度のロースペックPC2号ではfmt=22は再生できたが
今日fmt=35のワイド画面でも作業用のPen3機だと音ズレが生じたし
リアルタイム再生しようとしたら結構転送速度的にもきつかったので
全部ダウンロードするのをまたなくてもバッファリング時間は長くなりがち
音は変わらないので直接視聴はfmt=18に限るなと感じた。

あとクリップボードを使っているがprimaryでも良いかもしれない。
posted by Xo_ox at 20:00| Comment(0) | perl | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。