2012-07-08 15 views
8

Desidero un collegamento diretto ai video di Vimeo con uno script PHP. Sono riuscito a trovarli manualmente, ma il mio script PHP non funziona. Qui è l'iniziativa: Per esempio ho preso questo video: http://vimeo.com/22439234Ottieni video di collegamento diretto da Vimeo in PHP

Quando vai sulla pagina, Vimeo genera una firma associata con il timestamp corrente e questo video. Queste informazioni sono memorizzate in una variabile JavaScript, attorno alla riga 520 subito dopo: window.addEvent ('domready', function() {

Poi, quando si fa clic su Play, il player HTML5 legge questo variabile e invia una richiesta 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= 

Ma funziona anche con:

http:// player.vimeo.com/play_redirect?clip_id=37111719&sig={SIGNATURE}&time={TIMESTAMP}&quality=sd 

Se questo URL non si apre con l'indirizzo IP che ha aperto http://vimeo.com/22439234, questo restituisce il codice HTTP 200 con un messaggio di errore.

Se questo URL viene aperto con l'indirizzo IP corretto, l'intestazione "Location" reindirizza per collegare il file video: http://av.vimeo.com/XXX/XX/XXXX.mp4?aksessionid=XXXX&token=XXXXX_XXXXXXXXX

Quando costruisco questo link http://player.vimeo.com/play_redirect?... manualmente ("tasto destro"> "codice sorgente ">" riga 520 ") funziona.

Ma con PHP e regex restituisce HTTP code 200 con un messaggio di errore.

Perché?

Dalle mie osservazioni, Vimeo non verifica le intestazioni di richiesta HTTP per http:// player.vimeo.com/play_redirect?... GET, HEAD, con biscotti, senza cookie, referrer, ecc ... non cambia.

Con PHP, utilizzo la funzione file_get_contents() e 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)); 
    } 

risposta

0

Provare ad aggiungere un user-agent valido alle intestazioni per ogni richiesta. Per questo devi usare cURL o HttpRequest invece file_get_contents().

Dopo tali manipolazioni ho ottenuto un collegamento funzionante per il download del file video.

Ecco il mio codice:

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); 
+0

non funziona qui, ho sempre avuto 1 come risultato – Magico

+0

Ho lo stesso risultato quando prova il codice. –

4

L'algoritmo simile a questo: i dati

  • ingresso: vimeoUrl.
  • content = getRemoteContent (vimeoUrl).
  • Analizza il contenuto per trovare ed estrarre il valore dall'attributo data-config-url .
  • Passare a data-config-url e caricare il contenuto come Oggetto JSON: $ video = json_decode ($ this-> getRemoteContent ($ video-> getAttribute ('data-config-url'))));
  • Restituisce $ video-> richiesta-> file-> h264-> sd-> url - questo restituirà un collegamento diretto per video di qualità SD.

Ecco la mia classe semplice, che funziona per questo momento.

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; 
    } 

} 

Usando:

$video = new VideoController; 
var_dump($video->getVimeoDirectUrl('http://vimeo.com/90747156')); 
Problemi correlati