J'ai vu qu'aujourd'hui vimeo a changé la façon dont ils diffusent les vidéos et que je ne peux plus les diffuser. J'ai vu cela lorsque je génère le lien vers la vidéo, qui était par exemple:
http://vimeo.com/moogaloop/play/clip:6649390/1eab2a25f30f1aadaf5e306d0f40fd6c/1292498602/?q=hd
Cela me redirige vers une page disant "Autorisation refusée". J'ai essayé d'utiliser curl, mais sans succès. J'ai flairé le trafic et j'ai vu qu'il diffusait quelque chose comme:
http://av.vimeo.com/02047/623/34209065.mp4?token=1292496582_34de09a6d13212cf26af08357d311c30
Quelqu'un sait-il comment obtenir l'URL de travail du fichier vidéo?
Voici comment je reçois les vidéos:
http://vimeo.com/video_id
.video_id
.http://vimeo.com/moogaloop/load/clip:video_id;
.analyser le XML et trouver les informations nécessaires:
Générez le lien:
$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
Si je le fais manuellement via le navigateur, cela fonctionne, mais si je le fais via le script, cela ne fonctionne pas.
Ce javascript fonctionne pour moi.
var player = document.getElementsByClassName("player")[0].getAttribute("id");
player = eval(player.replace("player_", "clip"));
var time = player.config.request.timestamp;
var sig = player.config.request.signature;
var clip_id = window.location.href.substring(17);
var url = "http://player.vimeo.com/play_redirect" +
"?clip_id=" + clip_id +
"&sig=" + sig +
"&time=" + time;
var v = document.getElementById("menu");
v.style.fontSize = "4em";
v.style.lineHeight = "1em";
v.innerHTML =
"<a href='" + url + "'>SD</a>, " +
"<a href='" + url + "&quality=hd'>HD</a>";
Warning Les méthodes décrites ci-dessus ne sont pas supportées par Vimeo. Rien ne garantit qu'ils fonctionnent actuellement ou continueront de fonctionner à l'avenir. Ils peuvent (et vont probablement) faire une pause à tout moment, sans préavis.
La seule méthode officiellement prise en charge pour accéder aux URL de fichiers vidéo consiste à utiliser le fichier API .
Si vous essayez d'accéder aux URL des vidéos que vous possédez, vous devez avoir un compte PRO.
Si vous essayez d'accéder aux URL de vidéos que vous ne possédez pas, vous devez incorporer la vidéo ou l'ouvrir avec l'application iOS Vimeo .
Pour votre information, l'exemple ci-dessus ne fonctionnera pas, mais c'est proche. Vous devez envoyer de faux cookies. En gros, lorsque vous visitez la page XML, vous devez récupérer les cookies, puis envoyer les cookies que vous avez précédemment reçus lors de la visite de l'URL de la vidéo finale. Alors voici comment vous le faites dans PHP (en utilisant Yii) avec curl:
public function actionVimeo($video_id)
{
$xml_url = "http://vimeo.com/moogaloop/load/clip:$video_id";
$ch = curl_init($xml_url);
$cookieFile = Yii::app()->basePath . '/runtime/vimeocookie'. time().'.txt'; //replace this line with code to generate a writeable path in your application
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); //the cookie file will be populated with cookies received while viewing the xml page
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //you need to send a user agent here and it must be the same below when you visit the video url
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
$xml = simplexml_load_string($output);
$request_signature = $xml->request_signature;
$request_signature_expires = $xml->request_signature_expires;
$vid_url = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=sd";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$vid_url);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //same user agent as on previous vimeo page you visited
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); //the cookies in that cookie file will be used while visiting the video URL
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); //vimeo changes the header location, so you gotta follow it
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$video = curl_exec($ch);
curl_close($ch);
unlink($cookieFile); //remove the temporary cookie file
$savePath = Yii::app()->basePath . '/runtime/testvim.mp4'; //change this to a path your application can write the final video to
file_put_contents($savePath, $video);
exit;
}
L'algorithme ressemble à ceci:
Voici mon cours simple, qui travaille pour ce moment:
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;
}
}
En utilisant:
$video = new VideoController;
var_dump($video->getVimeoDirectUrl('http://vimeo.com/90747156'));
Les réponses à cette question sur SuperUser étant obsolètes, j'ai donc pensé les poster ici (réputation insuffisante pour y poster)
Je viens donc d’enregistrer les demandes XHR avec Chrome devtools et la première demande concernait le fichier json contenant le lien vers la vidéo hébergée sur CDN d’akamai avec le jeton fourni par akamai. Ce jeton est important. C'est un hash qui inclut un horodatage, donc les liens pour les vidéos ici devront être téléchargés assez rapidement ou les demandes seront refusées.
Le format de ce fichier JSON était le suivant:
https://player.vimeo.com/video/VIDEO_ID/config?byline=0&collections=1&context=Vimeo%5CController%5CClipController.main&default_to_hd=1&outro=nothing&portrait=0&share=1&title=0&watch_trailer=0&s=6cffff97fffffffffff4ffffffff679ec66ffff_14ffffffff
Et puis j'ai juste cherché l'objet de la plus haute qualité dans le JSON (1080p) et téléchargé ce fichier. Dans le format:
https://fpdl.vimeocdn.com/vimeo-prod-skyfire-std-us/01/XXXXX/8/XXXX/XXXXXXXX.mp4?token=XXXXXXX-0xXXXXXXXXXXXXX
Notez que les X sont des nombres que j'ai remplacés pour des raisons de confidentialité.
Une approche rapide et sale serait:
$base = 'http://player.vimeo.com/play_redirect';
$curl = curl_init(sprintf('http://player.vimeo.com/video/%s', $_GET['id']));
curl_setopt_array($curl, array(
CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
CURLOPT_RETURNTRANSFER => true
));
preg_match('/g:(\{.*?\}),a/s', curl_exec($curl), $match);
curl_close($curl);
$json = json_decode($match[1])->request;
$url = sprintf('%s?quality=sd&clip_id=%s&time=%d&sig=%s',
$base,
$_GET['id'],
$json->timestamp,
$json->signature
);
$curl = curl_init($url);
curl_setopt_array($curl, array(
CURLOPT_HEADER => true,
CURLOPT_NOBODY => true,
CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'],
CURLOPT_RETURNTRANSFER => true
));
$headers = explode("\r\n", curl_exec($curl));
curl_close($curl);
foreach ($headers as $header) {
if ($header) {
header($header);
}
}