YouTube から動画をダウンロードする
探してみた。とりあえず、php のソース。
php が読めれば、perl が読める。perl が読めれば、php が読める
ま、最悪 perl から呼び出して使うって手もあるしね。こういうものは見つけたときの保存しておく。
そのためにこのサイトを立ち上げたのだ。なんてなw
<?php // 動画のURL $url = "http://www.youtube.com/watch?v=NGQrE3fM8w8"; // 拡張子のリスト $extension = array("5" => ".flv", "18" => ".mp4", "22" => ".mp4", "34" => ".flv", "35" => ".flv", "37" => ".mp4", "38" => ".mp4"); // HTMLファイルの取得 $html = file_get_contents($url); // HTMLからタイトルを獲得する preg_match("/<meta name=\"title\" content=\"([^\"]*)\">/s", $html, $matches); $title = $matches[1]; // 動画URLの取得 preg_match("/url_encoded_fmt_stream_map=([^\"]*)/i", $html, $matches); $dataset = explode("%2C", $matches[1]); for ($i = 0; $i < count($dataset); $i++) { preg_match("/^url%3D(.*)/i", $dataset[$i], $matches); if (count($matches) != 0) { $flvs = explode("&quality=", urldecode(urldecode($matches[1]))); preg_match("/&itag=(\d*)/i", $flvs[0], $itags); $video_url = $flvs[0]; $itag = $itags[1]; // 動画をDL if (isset($extension[$itag])) { echo "title : $title\n"; echo "itag : $itag\n"; echo "start download.\n"; $fp = fopen(mb_convert_encoding($title,"sjis","auto")."_fmt" . $itag . $extension[$itag], "wb"); $handle = fopen($video_url, "rb"); while (!feof($handle)) fwrite($fp, fread($handle, 8192)); echo "finish download.\n\n"; } } } ?>
技術情報として参考になりそうなサイト。
perl-users.jp/articles/advent-calendar/2010/hacker/23
パールも見つけたけど、syntaxhirightがうまく動いてないみたいで、一応コピーしてきたけどうまくはれるかな?
解説は、ごたぶんに漏れず上から目線でわけわかめ。「実に興味深いコードだ」だって、しらねーよ!ってな?ww
要するにユーチューブのcpanがありそうだってことだな。よしよし行けそうだw
almajiro.net/youtube-channel-save
use WWW::YouTube::Download::Channel; my $yt = WWW::YouTube::Download::Channel->new(); $yt->target_directory(‘/youtuve/thiers48′); #OPTIONAL. default is current dir $yt->apply_regex_filter(’24 horas|24H’); #OPTIONAL apply regex filters by title.. $yt->apply_regex_skip( ‘skip|this|title’ ); #OPTIONAL skip some titles $yt->newer_than( { #OPTIONAL filter videos by dates day => 1, month => 12, year => 2000 } ); $yt->leech_channel(‘thiers48′); #REQ $yt->download_all; #REQ find and download youtube videos
こっちの方がわかりやすそうだ。
blog.livedoor.jp/xaicron/archives/50764987.html
#!C:/Perl/bin/perl # Youtubeから最高画質の動画をダウンロードする # fmt35とかもいける use strict; use warnings; use utf8; use Encode; use LWP::UserAgent; use File::Basename; use Web::Scraper; use URI; use JSON qw/decode_json/; # ファイル名のエンコード my $enc = 'cp932'; # 引数 my $url = shift || die "Usage: $0 youtube_rul"; # スクレイピング my $uri = URI->new($url); my $scraper = scraper { process '/html/head/script[5]', script => 'html', process '/html/body/div/div[3]/h1', title => 'TEXT', }; my $result = $scraper->scrape($uri); # JSON取得 my $json; for my $line (split /\n/, $result->{script}) { if ($line =~ /^\s*var\s*swfArgs\s*=\s*({.*});/) { $json = HTML::Entities::decode_entities($1); last; } } my $swfArgs = decode_json $json; # 最高画質のfmt取得 my $fmt; for my $map (split /,/, $swfArgs->{fmt_map}) { next if $map =~ m|^(\d+)/(\d+)| and $2 eq '0'; # 2つ目の数値が0だったら存在しないっぽい? $fmt = "&fmt=$1"; last; } # 定義がなかったらfmt=18とする $fmt = '&fmt=18' unless $fmt; # ファイルの拡張子 my $suffix = $fmt =~ /(18|22)/ ? '.mp4' : '.flv'; # ダウンロードURL my $video_url = sprintf "http://www.youtube.com/get_video?video_id=%s&t=%s%s", $swfArgs->{video_id}, $swfArgs->{t}, $fmt; # 保存するファイル名 my $filename = encode $enc, $result->{title} . $suffix; # ファイルがあったら終了 die "File exists ($filename)" if -f $filename; # 進捗表示しつつダウンロード open my $wfh, '>', $filename or die "$filename: $!"; binmode $wfh; print "$video_url\n"; print "Downloading -> $filename\n"; my $res = LWP::UserAgent->new->get( $video_url, ':content_cb' => sub { my ( $chunk, $res, $proto ) = @_; print $wfh $chunk; my $size = tell $wfh; if (my $total = $res->header('Content-Length')) { printf "%d/%d (%f%%)\r", $size, $total, $size/$total * 100; } else { printf "%d/Unknown bytes\r", $size; } }, ); close $wfh; # 後処理 print "\n", $res->status_line, "\n"; unlink $filename unless $res->is_success; exit 1;
スポンサーリンク