Skip to content

Instantly share code, notes, and snippets.

@sotarok
Created May 24, 2009 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sotarok/117150 to your computer and use it in GitHub Desktop.
Save sotarok/117150 to your computer and use it in GitHub Desktop.
<?php
/**
*
*
*/
define("YOUTUBE_URL", 'http://www.youtube.com/');
define("YOUTUBE_USER_UPLOAD_URL", 'http://gdata.youtube.com/feeds/api/users/%s/uploads');
require_once 'initializer.php';
require_once 'HTTP/Request2.php';
$format_map = array(
5 => 'FLV Normal',
6 => 'FLV HQ',
13 => '3GP Mobile',
17 => '3GP Mobile(MPEG-4)',
18 => 'MP4 HQ(H.264)',
22 => 'MP4 HD(H.264)',
34 => 'FLV Normal(H.264)',
35 => 'FLV HQ(H.264)',
);
$target_youtube_ids = array(
"PerfumeWave",
);
$max_results = 50;
$options = array(
//'author' => $target_youtube_id,
);
if ($argc == 2) {
if ($argv[1] == "help") {
echo <<<EOF
Usage:
php get_video.php [Optoins]
Optoins:
help show this help.
id[,id,...] download all videos uploaded by user.
EOF;
exit;
}
$target_youtube_ids = explode(",", $argv[1]);
}
$total = 0;
try
{
foreach ($target_youtube_ids as $target_youtube_id) {
$i = 1;
$movie_exists = true;
while($movie_exists) {
$url = sprintf(YOUTUBE_USER_UPLOAD_URL, $target_youtube_id) . "?" . http_build_query(array('start-index' => $i, 'max-results' => $max_results));
echo "Loading: " . $url . " ... ";
$entries = load_xpath($url, "//entry");
echo count($entries) . " entries loaded\n";
foreach ($entries as $entry) {
$id = basename($entry->id);
echo "\tID: " . $id . " ... \n";
echo "\tTitle: " . $entry->title . " ... \n";
$b = new HTTP_Request2(YOUTUBE_URL . "get_video_info?" . http_build_query(array('video_id' => $id)));
$res = $b->send();
parse_str($res->getBody(), $query);
$token = $query['token'];
// 一番質の良いフォーマットを選択
echo "\tFormat avaliables: " . $query['fmt_map'] . "\n"; // for debug
$format = 18;
foreach(explode(",", $query['fmt_map']) as $fmt) {
$fmt_tmp = explode("/", $fmt);
if ($fmt_tmp[0] == 22) {
$format = $fmt_tmp[0];
break;
} else if ($fmt_tmp[0] == 35) {
$format = $fmt_tmp[0];
}
}
// ビデオにリダイレクトされるURLへGET
$request_url = YOUTUBE_URL . "get_video?" . http_build_query(array('video_id' => $id, 't' => $token, 'fmt' => $format));
echo "\t\tTo get video_url: " . $request_url . "\n";
echo "\t\tQuarity: " . $format_map[$format] . "\n";
$b->setUrl($request_url);
$res = $b->send();
// headerからビデオURLを取得
$headers = $res->getHeader();
$video_url = $headers['location'];
$video_filename = str_replace(array("/", ",", "'", "\"", " ", "!", ".", ), "_", $entry->title);
echo "\t\tURL fetched: " . $video_url . "\n";
// header だけげとー
foreach (get_headers($video_url) as $h) {
if (preg_match("@^Content-Disposition@", $h)) {
preg_match("@filename=\"[^\.]+?(\.[0-9a-zA-Z]+)\"@", $h, $out);
$video_ext = $out[1];
break;
}
}
$video_filename = VIDEO_DATA_DIR . "/" . $video_filename . $video_ext;
if (!file_exists($video_filename) || filesize($video_filename) == 0) {
if (file_put_contents($video_filename, file_get_contents($video_url), FILE_BINARY)) {
echo "\tdone.\n";
}
else {
echo "\tFAILED!\n";
}
}
else {
echo "\tfile exists, skipped.\n";
}
echo "\n";
}
$total += count($entries);
$i += $max_results;
if (count($entries) < $max_results) {
$movie_exists = false;
}
}
}
echo "\n";
echo "Total: " . $total . "\n";
}
catch(Exception $e) {
echo "Exception:\n\t";
echo $e->getMessage();
echo "\n";
}
<?php
/**
*
*
*/
initializer();
function initializer()
{
ini_set("memory_limit", "1G");
define_ifnot_defined("BASE_DIR", dirname(__FILE__));
define_and_mkdir("HTML_DATA_DIR", BASE_DIR . "/html");
define_and_mkdir("IMAGE_DATA_DIR", BASE_DIR . "/images");
define_and_mkdir("VIDEO_DATA_DIR", BASE_DIR . "/videos");
}
function define_ifnot_defined($key, $value)
{
if (!defined($key)) {
define($key, $value);
}
}
function define_and_mkdir($def_name, $dir_name)
{
if (!defined($def_name)) {
define($def_name, $dir_name);
}
if (!is_dir($dir_name)) {
if (!mkdir($dir_name)) {
throw new Exception (sprintf("Error: mkdir failed [%s]", $dir_name));
}
}
}
function load_xpath($url, $xpath)
{
require_once 'HTTP/Request2.php';
if (!class_exists('HTTP_Request2')) {
throw new Exception("Error: PEAR::HTTP_Request2 required!");
}
$b = new HTTP_Request2($url);
$res = $b->send();
if ($res->getStatus() != '200') {
throw new Exception(sprintf("Error: Youtube.com returned status %s!", $res->getStatus()));
}
return simplexml_import_dom(@DOMDocument::loadHTML($res->getBody()))->xpath($xpath);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment