Мне нужна прямая ссылка на видео с Vimeo с PHP-скриптом. Мне удалось найти их вручную, но мой PHP-скрипт не работает. Вот такая инициатива: например, я снял это видео: http://vimeo.com/22439234
Когда вы переходите на страницу, Vimeo генерирует подпись, связанную с текущей меткой времени и этим видео. Эта информация хранится в переменной JavaScript вокруг строки 520 сразу после: window.addEvent ('domready', function () {
Затем, когда вы нажимаете «Воспроизвести», игрок HTML5 считывает эту переменную и отправляет HTTP-запрос:
http:// player.vimeo.com/play_redirect?clip_id=37111719&sig={SIGNATURE}&time={TIMESTAMP}&quality=sd&codecs=H264,VP8,VP6&type=moogaloop_local&embed_location=
Но он также работает с:
http:// player.vimeo.com/play_redirect?clip_id=37111719&sig={SIGNATURE}&time={TIMESTAMP}&quality=sd
Если этот URL-адрес не открывается с IP-адресом, который был открыт http://vimeo.com/22439234 , это возвращает код HTTP 200 с сообщением об ошибке.
Если этот URL-адрес открывается с правильным IP-адресом, заголовок «Location» перенаправляется на ссылку на видеофайл: http://av.vimeo.com/XXX/XX/XXXX.mp4?aksessionid=XXXX&token=XXXXX_XXXXXXXXX
Когда я создаю эту ссылку http://player.vimeo.com/play_redirect?...
вручную («правый клик»> «исходный код»> «строка 520»), он работает.
Но с PHP и регулярным выражением он возвращает HTTP code 200
с сообщением об ошибке.
Зачем ?
Из моих наблюдений Vimeo не проверяет заголовки HTTP-запроса для http:// player.vimeo.com/play_redirect?...
GET
, HEAD
, с http:// player.vimeo.com/play_redirect?...
, без cookies, referrer и т. Д. … не изменяется.
С PHP я использую функцию file_get_contents()
и get_headers()
.
<?php function getVimeo($id) { $content = file_get_contents('http://vimeo.com/'.$id); if (preg_match('#document\.getElementById\(\'player_(.+)\n#i', $content, $scriptBlock) == 0) return 1; preg_match('#"timestamp":([0-9]+)#i', $scriptBlock[1], $matches); $timestamp = $matches[1]; preg_match('#"signature":"([a-z0-9]+)"#i', $scriptBlock[1], $matches); $signature = $matches[1]; $url = 'http://player.vimeo.com/play_redirect?clip_id='.$id.'&sig='.$signature.'&time='.$timestamp.'&quality=sd'; print_r(get_headers($url, 1)); }
Алгоритм выглядит так:
Вот мой простой класс, который работает на этот момент.
class VideoController { /** * @var array Vimeo video quality priority */ public $vimeoQualityPrioritet = array('sd', 'hd', 'mobile'); /** * @var string Vimeo video codec priority */ public $vimeoVideoCodec = 'h264'; /** * Get direct URL to Vimeo video file * * @param string $url to video on Vimeo * @return string file URL */ public function getVimeoDirectUrl($url) { $result = ''; $videoInfo = $this->getVimeoVideoInfo($url); if ($videoInfo && $videoObject = $this->getVimeoQualityVideo($videoInfo->request->files)) { $result = $videoObject->url; } return $result; } /** * Get Vimeo video info * * @param string $url to video on Vimeo * @return \stdClass|null result */ public function getVimeoVideoInfo($url) { $videoInfo = null; $page = $this->getRemoteContent($url); $dom = new \DOMDocument("1.0", "utf-8"); libxml_use_internal_errors(true); $dom->loadHTML('<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $page); $xPath = new \DOMXpath($dom); $video = $xPath->query('//div[@data-config-url]'); if ($video) { $videoObj = json_decode($this->getRemoteContent($video->item(0)->getAttribute('data-config-url'))); if (!property_exists($videoObj, 'message')) { $videoInfo = $videoObj; } } return $videoInfo; } /** * Get vimeo video object * * @param stdClass $files object of Vimeo files * @return stdClass Video file object */ public function getVimeoQualityVideo($files) { $video = null; if (!property_exists($files, $this->vimeoVideoCodec) && count($files->codecs)) { $this->vimeoVideoCodec = array_shift($files->codecs); } $codecFiles = $files->{$this->vimeoVideoCodec}; foreach ($this->vimeoQualityPrioritet as $quality) { if (property_exists($codecFiles, $quality)) { $video = $codecFiles->{$quality}; break; } } if (!$video) { foreach (get_object_vars($codecFiles) as $file) { $video = $file; break; } } return $video; } /** * Get remote content by URL * * @param string $url remote page URL * @return string result content */ public function getRemoteContent($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 20); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); curl_setopt($ch, CURLOPT_USERAGENT, 'spider'); $content = curl_exec($ch); curl_close($ch); return $content; } }
С помощью:
$video = new VideoController; var_dump($video->getVimeoDirectUrl('http://vimeo.com/90747156'));
Попробуйте добавить действительный пользовательский агент в заголовки для каждого запроса. Для этого вы должны использовать cURL или HttpRequest вместо file_get_contents ().
После таких манипуляций я получил рабочую ссылку для загрузки видеофайла.
Вот мой код:
function getVimeo($id) { // get page with a player $queryResult = httpQuery('http://vimeo.com/' . $id); $content = $queryResult['content']; if (preg_match('#document\.getElementById\(\'player_(.+)\n#i', $content, $scriptBlock) == 0) return 1; preg_match('#"timestamp":([0-9]+)#i', $scriptBlock[1], $matches); $timestamp = $matches[1]; preg_match('#"signature":"([a-z0-9]+)"#i', $scriptBlock[1], $matches); $signature = $matches[1]; $url = 'http://player.vimeo.com/play_redirect?clip_id=' . $id . '&sig=' . $signature . '&time=' . $timestamp . '&quality=sd'; // make the request for getting a video url #print_r(get_headers($url, 1)); $finalQuery = httpQuery($url); return $finalQuery['redirect_url']; } // make queries via CURL function httpQuery($url) { $options = array( CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/535.19', CURLOPT_RETURNTRANSFER => true, ); $ch = curl_init($url); curl_setopt_array($ch, $options); $content = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); $result = $info; $result['content'] = $content; return $result; } echo getVimeo(22439234);