php 如何找到 vimeo 视频的下载链接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4460394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I find download links for vimeo videos?
提问by pocko
I saw that today vimeo changed the way they are streaming the videos and I can't stream their videos anymore. I saw that when I generate the link to the video, which was for example:
我看到今天 vimeo 改变了他们播放视频的方式,我不能再播放他们的视频了。我在生成视频链接时看到了这一点,例如:
http://vimeo.com/moogaloop/play/clip:6649390/1eab2a25f30f1aadaf5e306d0f40fd6c/1292498602/?q=hd
It's redirecting me to a page saying "Permission denied". I tried using curl, but without any success. I sniffed the traffic and I saw that it's streaming from something like:
它将我重定向到一个页面,上面写着“权限被拒绝”。我尝试使用 curl,但没有成功。我嗅了嗅流量,我看到它来自以下内容:
http://av.vimeo.com/02047/623/34209065.mp4?token=1292496582_34de09a6d13212cf26af08357d311c30
Does anybody know how to get the working URL to the video file?
有人知道如何获取视频文件的工作 URL 吗?
The way I'm getting the videos at the moment is:
我目前获取视频的方式是:
- Choose link
http://vimeo.com/video_id
. - Get only the
video_id
. - Get the XML for the video
http://vimeo.com/moogaloop/load/clip:video_id;
. parse the XML and find the necessary information:
- request_signature
- request_signature_expires
- isHD
Generate the link:
$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
- 选择链接
http://vimeo.com/video_id
。 - 只获取
video_id
. - 获取视频的 XML
http://vimeo.com/moogaloop/load/clip:video_id;
。 解析 XML 并找到必要的信息:
- 请求签名
- request_signature_expires
- 高清
生成链接:
$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
If I do this manually through the browser it works, but if I do it through the script it doesn't.
如果我通过浏览器手动执行此操作,则它可以工作,但如果我通过脚本执行此操作,则不会。
回答by pocko
After spending a few hours on finding out how I can get the direct link to vimeo I found a good solution. So here are the steps for the users who want to download and stream video src directly from vimeo. Keep in mind that they block all IP addresses and probably hosts which are downloading the videos in this way, so I just stopped using their services and I will never use them again :).
在花了几个小时找出如何获得 vimeo 的直接链接后,我找到了一个很好的解决方案。因此,这里是想要直接从 vimeo 下载和流式传输视频 src 的用户的步骤。请记住,他们会阻止所有 IP 地址以及可能以这种方式下载视频的主机,所以我只是停止使用他们的服务,我再也不会使用它们了 :)。
Steps to get the video sources:
获取视频源的步骤:
- choose link
http://vimeo.com/video_id
- get only the
video_id
- get the xml for the video
http://vimeo.com/moogaloop/load/clip:video_id;
parse the xml and I find the necessary information I need:
request_signature
request_signature_expires
isHD
Then I generate the link:
$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
Then if you are php dev, you call wget command through exec in this way
exec("wget -b '$video_link' -a 'wget.log' -O -");
Then you read the log and find out the link you are looking for. You can simply parse the log file. The direct link is between "Location: " and "[following]"
You return the direct link and clean the log file :)
- 选择链接
http://vimeo.com/video_id
- 只得到
video_id
- 获取视频的 xml
http://vimeo.com/moogaloop/load/clip:video_id;
解析 xml,我找到了我需要的必要信息:
request_signature
request_signature_expires
isHD
然后我生成链接:
$video_link = "http://vimeo.com/moogaloop/play/clip:".$video_id."/".$request_signature."/".$request_signature_expires."/?q=".$quality."";
那么如果你是php dev,就这样通过exec调用wget命令
exec("wget -b '$video_link' -a 'wget.log' -O -");
然后您阅读日志并找出您正在寻找的链接。您可以简单地解析日志文件。直接链接位于“位置:”和“[以下]”之间
您返回直接链接并清理日志文件:)
NOTE: keep in mind again that this won't work forever. Sooner or later they will block your ip :).
注意:再次记住,这不会永远有效。迟早他们会阻止你的IP :)。
回答by Steven Penny
This javascript works for me.
这个javascript对我有用。
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>";
回答by Dashron
WarningThe methods described above are not supported by Vimeo. There is no assurance they work right now, or will continue working in the future. They can (and likely will) break at any moment, without any prior notice.
警告Vimeo 不支持上述方法。无法保证它们现在可以工作,或者将来会继续工作。它们可以(并且很可能会)随时中断,无需任何事先通知。
The only officially supported method of accessing video file URLs is through the API.
访问视频文件 URL 的唯一官方支持的方法是通过API。
If you are trying to access the URLs of videos you own, you must have a PRO account.
如果您尝试访问您拥有的视频的 URL,您必须拥有 PRO 帐户。
If you are trying to access the URLs of videos you don't own, you should embed the video, or open it with the Vimeo iOS app.
如果您尝试访问不属于您的视频的 URL,您应该嵌入视频,或使用 Vimeo iOS 应用程序打开它。
回答by nemozny
No need for any scripts, let alone PHP.
不需要任何脚本,更不用说 PHP。
I wanted to download protected video (embedded on specific website), that even on vimeo.com cannot be played due to "Privacy settings".
我想下载受保护的视频(嵌入在特定网站上),由于“隐私设置”,即使在 vimeo.com 上也无法播放。
Simply fire-up Developer tools (Opera Dragonfly, Chrome Developer tools, whatever), choose Network and there you go:
只需启动开发者工具(Opera Dragonfly、Chrome 开发者工具等等),选择 Network 就可以了:
http://pdl.vimeocdn.com/23062/181/302074466.mp4?token2=1424299768_bbeb6039c037cd429cd560d668ec851e&aksessionid=1f4d289cd1a3abe1
Method: Get
Status text: 206 Partial content
Type: video/mp4
http://pdl.vimeocdn.com/23062/181/302074466.mp4?token2=1424299768_bbeb6039c037cd429cd560d668ec851e&aksessionid=1f4d289 cd1a6/
部分内容
:获取视频
内容
:文本2
Just copy that first URL and download with some tool (I used "wget").
Saved.
只需复制第一个 URL 并使用一些工具下载(我使用了“wget”)。
已保存。
回答by Brad Barrows
The answers for this on SuperUser were out of date so I thought I would post it here (not enough reputation to post there)
SuperUser 上的答案已经过时,所以我想我会在这里发布它(没有足够的声誉在那里发布)
So I just recorded XHR requests with Chrome devtools and the first request was for the the json file containing the link to the akamai CDN hosted video along with the token akamai provides. This token is important. It is hash that includes a timestamp so the links for the videos here will need to be downloaded somewhat quickly or requests will be refused.
所以我只是用 Chrome devtools 记录了 XHR 请求,第一个请求是针对包含指向 akamai CDN 托管视频的链接以及 akamai 提供的令牌的 json 文件的请求。这个令牌很重要。它是包含时间戳的哈希值,因此此处视频的链接需要快速下载,否则请求将被拒绝。
The format for this JSON file was in the form:
此 JSON 文件的格式为:
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
And then I just looked for the highest quality object in the JSON (1080p) and download that file. In the format:
然后我只是在 JSON (1080p) 中寻找最高质量的对象并下载该文件。格式如下:
https://fpdl.vimeocdn.com/vimeo-prod-skyfire-std-us/01/XXXXX/8/XXXX/XXXXXXXX.mp4?token=XXXXXXX-0xXXXXXXXXXXXXX
Note the Xs are numbers I replaced for privacy.
请注意,X 是我为了隐私而替换的数字。
回答by faceyspacey.com
FYI, the above example won't work, but it's close. You need to send fake cookies. So basically when you visit the page with the XML, you need to grab the cookies, and then send those cookies you previously received while visiting the final video url. So here's how you do it in PHP (using Yii) with curl:
仅供参考,上面的例子不起作用,但它很接近。您需要发送假 cookie。所以基本上当你访问带有 XML 的页面时,你需要获取 cookie,然后在访问最终视频 url 时发送你之前收到的那些 cookie。所以这里是你如何在 PHP(使用 Yii)和 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;
}
回答by k3min
A quick and dirty approach would be:
一种快速而肮脏的方法是:
$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);
}
}
回答by Alexander Yarovoy
The algorithm looks like this:
该算法如下所示:
- Input data: vimeoUrl.
- content = getRemoteContent(vimeoUrl).
- Parse content to find and extract the value from data-config-url attribute.
- Navigate to data-config-url and load the content as JSON Object: $video = json_decode($this->getRemoteContent($video->getAttribute('data-config-url')));
- Return $video->request->files->h264->sd->url — this will return a direct link for SD quality video.
- 输入数据:vimeoUrl。
- content = getRemoteContent(vimeoUrl)。
- 解析内容以从 data-config-url 属性中查找并提取值。
- 导航到 data-config-url 并将内容加载为 JSON 对象: $video = json_decode($this->getRemoteContent($video->getAttribute('data-config-url')));
- 返回 $video->request->files->h264->sd->url — 这将返回标清质量视频的直接链接。
Here is my simple class, that working for this 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;
}
}
Using:
使用:
$video = new VideoController;
var_dump($video->getVimeoDirectUrl('http://vimeo.com/90747156'));