Когда-то давным-давно, аж 22 июня 2007 года, на блоге одного хорошего человека появился занятный скрипт, который позволяет получать прямые ссылки на flv-файлы с YouTube для дальнейшего их скачивания себе локально (не мне, видать, одному надоело разгребать кеш Оперы в поисках скачанных флешек
). Идея была классной, но скрипт почему-то работать отказался. Пришлось долго и муторно копаться. Результатом мытарств стала пара классов, написанных на PHP5 (на баяне не играюна PHP4.x, уж извините, не пишу: двадцать первый век на дворе, шестая версия на подходе, а пятой и вообще четвертый год пошёл). Кода получилось несколько больше, чем в оригинале, зато работает как часы. А еще он умеет выдирать название ролика
. Всю грязную работу выполняют два класса:
- httpClient – объектно-риентированная обёртка к функциям библиотеки cURL. Простенький и чертовски удобный класс (мне так кажется, по крайней мере
. - YouTube – непосредственно парсер кода.
Будем считать, что эти классы лежат в файлах httpclient.php и youtube.php соответственно. Тогда скрипт морды будет выглядеть примерно так:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>YouTube DirectLink Extractor</title>
</head>
<body>
<h1>YouTube DirectLink Extractor</h1>
<form method="get">
<label>Enter Youtube URL:</label>
<input type="text" name="url" value="<?php echo @$_GET['url'] ?>" size="60" /?
<button type="submit">Get direct link</button>
</form>
<?php if (isset($_GET['url'])): ?>
<pre>
<?php
include_once 'httpclient.php';
include_once 'youtube.php';
$client = new httpClient();
$client->setProxy('proxy.server.ru', 3128);
$youtube = new YouTube();
$youtube->setHttpClient($client);
/**
* Execute programme
*
*/
$result = $youtube->getResult($_GET['url']);
/**
* Display all results as hash
*
*/
print_r($result);
/**
* or output title of url indepently
*
*/
print 'URL: ' .$youtube->getUrl().'<br />';
print 'Title: '.$youtube->getTitle().'<br />';
?>
</pre>
<?php endif; ?>
</body>
</html>
А вот и исходные коды классов: httpclient.php:
class httpClient
{
/**
* Свойство, хранящее дескриптор соединения
*
* @var resource
*/
private $_curl = null;
/**
* Свойство, сохраняющее ответ сервера на запрос
*
* @var stromg
*/
private $_response = '';
/**
* Конструктор класса
*
* @param void
* @return void
*/
public function __construct()
{
$this->_curl = curl_init();
$this->_setOption(CURLOPT_RETURNTRANSFER, true);
}
/**
* Устанавливает параметры дескриптора CURL
*
* @param integer $option
* @param mixed $value
* @return void
*/
private function _setOption($option, $value)
{
curl_setopt($this->_curl, $option, $value);
}
/**
* Выполняет HTTP-запрос и возвращает ответ сервера
*
* @param string $url
* @param boolean $header
* @return string
*/
public function get($url, $header = false)
{
$this->_setOption(CURLOPT_URL, $url);
$this->_setOption(CURLOPT_HEADER, $header);
return curl_exec($this->_curl);
}
/**
* Устанавливает адрес и порт прокси]
*
* @param string $host
* @param integer $port
* @return void
*/
public function setProxy($host, $port = 3128)
{
$this->_setOption(CURLOPT_PROXY, $host);
$this->_setOption(CURLOPT_PROXYPORT, $port);
}
/**
* Деструктор класса
*
* @param void
* @return void
*/
public function __destruct()
{
curl_close($this->_curl);
}
}
… и youtube.php
class YouTube
{
/**
* Свойство, хранящее указатель на объе
*
* @var httpRequest
*/
private $_httpClient;
/**
* Информация о клипе (по умолчанию пустая
)
*
* @var httpRequest
*/
private $_result = array('url' => null, 'title' => null);
/**
* Устанавливает используемый HTTP-клиент
*
* @param httpClient $client
* @return void
*/
public function setHttpClient(httpClient $client)
{
$this->_httpClient = $client;
}
/**
* Выполняет запрос к серверу YouTube и возвращает хеш-массив с
* полученным данными
*
* @param string $url
* @return array
*/
public function getResult($url)
{
return $this->_parse($url)->_result;
}
/**
* Непосредственно парсинг UHTML-страничек и вычленение заголовков с
* перенаправлениями.
*
* @param string $url
* @return YouTube
*/
private function _parse($url)
{
$code = $this->_httpClient->get($url);
if (preg_match('/var fs = window.open( "/(.*?)" + "(.*?)" ,/si', $code, $match)) {
$code = $this->_httpClient->get('http://youtube.com/'.$match[1]);
$title = $match[2];
if (preg_match('/"/player2.swf?(.*)", "player"/si', $code, $match)) {
$url = 'http://youtube.com/get_video.php?'.$match[1]; // работает
$code = $this->_httpClient->get($url, true);
if (preg_match('/Location:s*?(.*?)n/si', $code, $match)) {
$this->_result['url'] = trim($match[1]);
$this->_result['title'] = urldecode($title);
}
}
}
return $this;
}
/**
* Возвращает URL видео
*
* @param void
* @return string
*/
public function getUrl()
{
return $this->_result['url'];
}
/**
* Возвращает название видео
*
* @param void
* @return string
*/
public function getTitle()
{
return $this->_result['title'];
}
}
Возвращаемая скриптом ссылка является прямой: клик по ней приведет к скачиванию ролика. Название, к сожалению, по дефолту будет «vet_video», но можно ведь и переименовать файл руками, зная название ролика
. Можно и немного расширить функционал скрипта таким образом, чтобы он автоматом начинал выкачивать файл и предлагал имя, соответствующее названию ролика… Но это уже будет другая история
А пока хотелось бы услышать отзывы, замечания, комментарии. И совет опытных блоггеров: какой лучше всего использовать клиент для постинга? Пользоваться веб-интерфейсом TinyMCE не очень хочется
UPD.: т.к. редакотор не может по-человечески обращаться с кодом и считает своим долгом поубивать лишние (по его мнению, естественно) бекслеши из регулярных выражений, думаю, что лучше выложить исходники файлов (уберите расширение .txt из имени файла):
Комментарии (13)
27 Август 2007 в 09:53
[...] php скрипт – скачать видео с youtube [updated] Функциональная и более мастевая версия [...]
27 Август 2007 в 09:59
Красавчик!!!
На счет клиента, даже не знаю. Раньше Windows Live Writer был более-менее. Но последнии версии у меня почему-то упрямо не желают работать с кирилицей. Попробуй, может то у меня руки сильно кривые.
28 Август 2007 в 06:17
В нете сотни сервисов для скачки видео с Yutube и конвертирования (в avi например)
28 Август 2007 в 06:21
Хм… ну что ж поделаешь, стало быть одним велосипедом в сети стало больше
23 Сентябрь 2007 в 13:24
Ссылка на httpclient.php не открывется
25 Сентябрь 2007 в 22:09
Спасибо, исправлено
27 Декабрь 2007 в 06:40
А как насчет расширить функционал, чтобы он предлагал скачать с уже нормальным именем файла?
27 Декабрь 2007 в 10:33
А в чём проблема?
27 Декабрь 2007 в 19:49
В том, что я не знаю, как это сделать))
28 Декабрь 2007 в 06:32
Я не ставил перед собой целью выложить готовое решение, просто показал примерный подход, более того, не исключаю, что у них там всё уже поменялось и этот код нерабочий. Но показать направление, в котором надо копать, он (код) в состоянии.
Разбирайтесь, что делает скрипт. Если совсем лениво разбираться, то платите тем, кому не лениво. Сделают в лучшем виде
20 Май 2008 в 12:02
Ну, я бы не сказал, что это велосипед, так как веб-сервис это веб-сервис, а скрипт можно внедрить в какое-нибудь свое решение. Что, собственно, я и собираюсь сейчас сделать. Автору спасибо, что сэкономил мне кучу времени. Приступаю к тестированию
22 Июнь 2008 в 13:44
Новый код для скачивания с YouTube:
http://forum.armdex.com/index.php?act=ST&f=35&t=4657&st=0#entry67341
2 Октябрь 2008 в 03:23
Создание все новых и новых программ для скачивания с Tube приведет к повсеместному скачиванию…а потом выдавания этих же роликов за свои! Мда, господа, палка о двух концах!